Форум сайта python.su
Добрый день.
Использую Python 3.1.
Перестали работать передача параметров в метод execute. Что делаю:
# -*- coding: utf-8 -*-
import MySQLdb
try:
con = MySQLdb.connect(host="localhost", user="root", passwd="5213", db="test")
cur = con.cursor()
cur.execute('SET NAMES `utf8`')
cur.execute("""SELECT `name` FROM `city` WHERE `id_city`=%d""", (1,))
for row in cur:
print(row[0])
except MySQLdb.Error:
print(con.error())
cur.execute("""SELECT `name` FROM `city` WHERE `id_city`=?""", (1,))
cur.execute("""SELECT `name` FROM `city` WHERE `id_city`=(%(ids)d)""", { 'ids': 1 })
Офлайн
Установил Python 2.7 и в нём замечательно работает.
Посмотрел что в реализации модуля.
MySQLdb для Python 2.7
def execute(self, query, args=None):
"""Execute a query.
query -- string, query to execute on server
args -- optional sequence or mapping, parameters to use with query.
Note: If args is a sequence, then %s must be used as the
parameter placeholder in the query. If a mapping is used,
%(key)s must be used as the placeholder.
Returns long integer rows affected, if any
"""
del self.messages[:]
db = self._get_db()
charset = db.character_set_name()
if isinstance(query, unicode):
query = query.encode(charset)
if args is not None:
query = query % db.literal(args)
try:
r = self._query(query)
except TypeError, m:
if m.args[0] in ("not enough arguments for format string",
"not all arguments converted"):
self.messages.append((ProgrammingError, m.args[0]))
self.errorhandler(self, ProgrammingError, m.args[0])
else:
self.messages.append((TypeError, m))
self.errorhandler(self, TypeError, m)
except:
exc, value, tb = sys.exc_info()
del tb
self.messages.append((exc, value))
self.errorhandler(self, exc, value)
self._executed = query
if not self._defer_warnings: self._warning_check()
return r
def execute(self, query, args=None):
"""Execute a query.
query -- string, query to execute on server
args -- optional sequence or mapping, parameters to use with query.
Note: If args is a sequence, then %s must be used as the
parameter placeholder in the query. If a mapping is used,
%(key)s must be used as the placeholder.
Returns long integer rows affected, if any
"""
del self.messages[:]
db = self._get_db()
charset = db.character_set_name()
if args is not None:
if isinstance(query, bytes):
query = query.decode();
if isinstance(args, dict):
query = query.format( **db.literal(args) )
elif isinstance(args, tuple) or isinstance(args, list):
query = query.format( *db.literal(args) )
else:
query = query.format( db.literal(args) )
if isinstance(query, str):
query = query.encode(charset);
try:
r = self._query(query)
except TypeError as m:
if m.args[0] in ("not enough arguments for format string",
"not all arguments converted"):
self.messages.append((ProgrammingError, m.args[0]))
self.errorhandler(self, ProgrammingError, m.args[0])
else:
self.messages.append((TypeError, m))
self.errorhandler(self, TypeError, m)
except:
exc, value, tb = sys.exc_info()
del tb
self.messages.append((exc, value))
self.errorhandler(self, exc, value)
self._executed = query
if not self._defer_warnings: self._warning_check()
return r
Офлайн
Судя по коду в 3.x используется метод format, который требует другой способ задания параметров (через фигурные скобки).
А вот в док-строке у метода execute указаны старые данные.
И вообще, насколько я помню, в версии 3 оператор % для строк считается deprecated.
Офлайн
Почему через фигурные?
if isinstance(args, dict):
query = query.format( **db.literal(args) )
elif isinstance(args, tuple) or isinstance(args, list):
query = query.format( *db.literal(args) )
else:
query = query.format( db.literal(args) )
Офлайн
Всё, я расковырял модуль, подзабыл я про обращение с методов format
cur.execute('SELECT name FROM city WHERE id_city={0}', 1)
cur.execute('SELECT name FROM city WHERE id_city={0:s}', 1)
cur.execute('SELECT name FROM city WHERE id_city={0}', (1,))
Офлайн