我使用SQLAlchemy声明来处理MySQL。
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, sessionmaker
import datetime
engine = create_engine('mysql+mysqldb://root:mypass@localhost/somedb')
Base = declarative_base()
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
class Item(Base):
__tablename__ = 'item'
id = Column(Integer, primary_key=True)
dt = Column(DateTime)
title = Column(UnicodeText)
Base.metadata.create_all(engine)
i = Item()
i.dt = datetime.datetime.now()
i.title = "hello world"
session.add(i)
session.commit()
此代码在session.commit()
上抛出异常:
sqlalchemy.exc.ProgrammingError: (ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s, %s)' at line 1") b'INSERT INTO item (dt, title) VALUES (%s, %s)' (datetime.datetime(2014, 5, 16, 20, 58, 7, 729245), 'hello world')
异常的完整堆栈跟踪在帖子的末尾。
我发现参数没有正确插入查询字符串。有query = query.format( *db.literal(args) ) in the file MySQLdb/cursors.py, on the line 163
行。 query
变量是一个字符串。 string.format
函数接受替换字段,例如{}
,{1}
,{23}
,而不是%s
。但查询变量中的替换字段为%s
。
因此,参数未插入查询中。
我可以通过在sqlalchemy/sql/compiler.py
文件变量BIND_TEMPLATES
中进行更改来解决问题。我已将'format': "%%s"
更改为'format': "{}"
。
但我清楚地知道人们成功使用sqlalchemy没有这个错误。这个问题的真正原因是什么?也许我已经安装了一些不兼容的版本?
我在Windows 7 x64上使用Python 3.4, Mysql连接器:MySQL_python-1.2.3-py3.4-win-amd64.egg
异常的完整堆栈跟踪:
Traceback (most recent call last):
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.1.3\helpers\pydev\pydevd.py", line 1539, in <module>
debugger.run(setup['file'], None, None)
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.1.3\helpers\pydev\pydevd.py", line 1150, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.1.3\helpers\pydev\_pydev_execfile.py", line 37, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc) #execute the script
File "C:/Work/midmay/midmay.parser/scripts/test.py", line 30, in <module>
session.commit()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 765, in commit
self.transaction.commit()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 370, in commit
self._prepare_impl()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 350, in _prepare_impl
self.session.flush()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 1903, in flush
self._flush(objects)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 2021, in _flush
transaction.rollback(_capture_exception=True)
File "C:\Python34\lib\site-packages\sqlalchemy\util\langhelpers.py", line 57, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "C:\Python34\lib\site-packages\sqlalchemy\util\compat.py", line 168, in reraise
raise value
File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 1985, in _flush
flush_context.execute()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 370, in execute
rec.execute(self)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 523, in execute
uow
File "C:\Python34\lib\site-packages\sqlalchemy\orm\persistence.py", line 64, in save_obj
mapper, table, insert)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\persistence.py", line 594, in _emit_insert_statements
execute(statement, params)
File "C:\Python34\lib\site-packages\sqlalchemy\engine\base.py", line 720, in execute
return meth(self, multiparams, params)
File "C:\Python34\lib\site-packages\sqlalchemy\sql\elements.py", line 317, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "C:\Python34\lib\site-packages\sqlalchemy\engine\base.py", line 817, in _execute_clauseelement
compiled_sql, distilled_params
File "C:\Python34\lib\site-packages\sqlalchemy\engine\base.py", line 947, in _execute_context
context)
File "C:\Python34\lib\site-packages\sqlalchemy\engine\base.py", line 1108, in _handle_dbapi_exception
exc_info
File "C:\Python34\lib\site-packages\sqlalchemy\util\compat.py", line 174, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=exc_value)
File "C:\Python34\lib\site-packages\sqlalchemy\util\compat.py", line 167, in reraise
raise value.with_traceback(tb)
File "C:\Python34\lib\site-packages\sqlalchemy\engine\base.py", line 940, in _execute_context
context)
File "C:\Python34\lib\site-packages\sqlalchemy\engine\default.py", line 435, in do_execute
cursor.execute(statement, parameters)
File "C:\Python34\lib\site-packages\mysql_python-1.2.3-py3.4-win-amd64.egg\MySQLdb\cursors.py", line 184, in execute
self.errorhandler(self, exc, value)
File "C:\Python34\lib\site-packages\mysql_python-1.2.3-py3.4-win-amd64.egg\MySQLdb\connections.py", line 37, in defaulterrorhandler
raise errorvalue
File "C:\Python34\lib\site-packages\mysql_python-1.2.3-py3.4-win-amd64.egg\MySQLdb\cursors.py", line 171, in execute
r = self._query(query)
File "C:\Python34\lib\site-packages\mysql_python-1.2.3-py3.4-win-amd64.egg\MySQLdb\cursors.py", line 330, in _query
rowcount = self._do_query(q)
File "C:\Python34\lib\site-packages\mysql_python-1.2.3-py3.4-win-amd64.egg\MySQLdb\cursors.py", line 294, in _do_query
db.query(q)
sqlalchemy.exc.ProgrammingError: (ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s, %s)' at line 1") b'INSERT INTO item (dt, title) VALUES (%s, %s)' (datetime.datetime(2014, 5, 16, 20, 58, 7, 729245), 'hello world')
答案 0 :(得分:0)
尝试添加__table_args__ = {}
。这对我有用:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
from sqlalchemy.orm import relation, relationship
DeclarativeBase = declarative_base(cls=DeferredReflection)
class MyItem(DeclarativeBase):
__tablename__ = 'myitem'
__table_args__ = {}
更新:我已经按原样运行你的代码(当然除了改变引擎的mysql url字符串之外)使用Python 2.7(x64,在Linux上)并且它运行没有任何问题(它创建了表并插入了'hello world'进去)。依赖关系:
MySQL-python==1.2.5
SQLAlchemy==0.9.2
更仔细地阅读你的帖子我发现你使用过Python 3.4。 http://docs.sqlalchemy.org/en/rel_0_9/changelog/migration_09.html州:
“所有SQLAlchemy模块和单元测试现在都可以很好地解决2.6前向的Python解释器,包括3.1和3.2解释器。”
这没有明确提及3.3和3.4。您可能在SA中遇到过一个错误,或者它还没有更新到3.4。我建议安装2.7(他们应能够在单个系统上共存),使用virtualenv for 2.7,安装deps并重新运行代码。
另一个可能的问题来源是3.4的MySQL驱动程序。我很伤心地说,但Python 3下*下MySQL的支持是严重缺乏:球队在我的工作中的驱动程序不仅漏水,但无法处理高负载下的许多连接。在修复驱动程序之前,最好使用2.7。那,或者只是改为Postgres作为db。
答案 1 :(得分:0)
我找到了解决方案。也许它不是最好的,它并不适合所有人。但在这里。
解决方案是安装 Mysql Connector 而不是 MySQLDb ,并将连接字符串从mysql+mysqldb://root:mypass@localhost/somedb
更改为mysql+connector://root:mypass@localhost/somedb
。
如果您是Windows用户(就像我一样),并且您遇到此问题:"Cannot open include file: 'config-win.h': No such file or directory" while installing mysql-python,那么您可以将Python版本从3.4降级到3.3并从此处下载预编译的Mysql Connector for python 3.3 :http://dev.mysql.com/downloads/connector/python/
它对我有用。感谢。