【发布时间】:2014-02-12 11:34:27
【问题描述】:
我是 SQLAlchemy 的新用户,并按照他们网站上的教程进行操作。 我运行了他们关于向数据库添加信息和查询虚拟数据库(内存中的sqlite)的教程。
在我认为我明白了之后,我尝试对一个真实的数据库进行测试 - mysql db。
我正在使用 pymysql 驱动程序版本 0.4(我知道它有点旧,但是在使用较新版本时我有其他错误,与此主题无关)。
我的代码如下:
def read_from_DB():
engine = create_engine('mysql+pymysql://***@***/test', echo=True)
Session = sessionmaker(bind=engine)
session=Session()
#insert = CpuTable(id='15',name= 'igal')
#session.add(insert)
#session.commit()
print()
print(str(session.query(CpuTable.id.label('id')).all()))
for cpu_id,cpu_name in session.query(CpuTable).all():
print(cpu_id,cpu_name)
我的堆栈跟踪如下:
C:\Python33\python.exe J:/working_dir/TLM/lib/DB_Wrapper/Lab_DB/DB_Reader.py
2014-02-12 11:23:57,193 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2014-02-12 11:23:57,193 INFO sqlalchemy.engine.base.Engine ()
2014-02-12 11:23:57,196 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%'
2014-02-12 11:23:57,196 INFO sqlalchemy.engine.base.Engine ()
2014-02-12 11:23:57,198 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2014-02-12 11:23:57,198 INFO sqlalchemy.engine.base.Engine ()
2014-02-12 11:23:57,199 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2014-02-12 11:23:57,199 INFO sqlalchemy.engine.base.Engine SELECT cpu.id AS id
FROM cpu
2014-02-12 11:23:57,199 INFO sqlalchemy.engine.base.Engine ()
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\engine\result.py", line 69, in __getitem__
KeyError: <sqlalchemy.sql.elements.Label object at 0x0000000003C6FDA0>
在处理上述异常的过程中,又发生了一个异常:
Traceback (most recent call last):
File "J:/working_dir/TLM/lib/DB_Wrapper/Lab_DB/DB_Reader.py", line 39, in <module>
read_from_DB()
File "J:/working_dir/TLM/lib/DB_Wrapper/Lab_DB/DB_Reader.py", line 26, in read_from_DB
print(str(session.query(CpuTable.id.label('id')).all()))
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\orm\query.py", line 2264, in all
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\orm\loading.py", line 75, in instances
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\orm\loading.py", line 75, in <listcomp>
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\orm\loading.py", line 74, in <listcomp>
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\orm\query.py", line 3440, in proc
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\engine\result.py", line 71, in __getitem__
File "C:\Python33\lib\site-packages\sqlalchemy-0.9.0-py3.3.egg\sqlalchemy\engine\result.py", line 317, in _key_fallback
sqlalchemy.exc.NoSuchColumnError: "Could not locate column in row for column 'cpu.id'"
在调试这个问题时,我设法发现我确实从数据库中得到了结果,只有当查询是select table.id 它返回为table_id。 (我和一些使用这个的朋友交谈过,他们确认它也发生在他们手上,只有他们的 SQLAlchemy 包装器知道如何处理这个问题,而我的会抛出这个错误)。注释掉的insert 行是为了检查我与数据库的连接,并检查它是否插入了数据,确实如此,查询部分是问题所在。在针对 sqlite 内存数据库进行测试时,它确实有效。
使用pymysql 驱动程序处理 MySQL db 时会出现什么问题?
尝试在网上搜索 1 天的类似问题甚至找不到 1。我的 sqlalchemy 版本是 0.9.1,我将其降级为 0.9,但问题仍然存在。
编辑: 采用不同的方法,我尝试编写不使用类映射的代码。这次我实际上设法检索了数据库中的数据。我添加了代码
metadata = MetaData()
cpu = Table('cpu',metadata,
Column('id',INTEGER,primary_key=True),
Column('name',String(50))
)
from sqlalchemy.sql import select
q = select([cpu])
conn = engine.connect()
result = conn.execute(q)
for row in result:
print(row)
因为我没有使用我创建的映射类,所以我认为 id 显示了类本身,可能会提供一些见解:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,INTEGER,String
class CpuTable(declarative_base()):
__tablename__ = 'cpu'
id = Column(INTEGER,primary_key=True)
name = Column(String(50))
def __repr__(self):
return "<cpu(id = '%s',name = '%s')>" % (self.id,self.name)
【问题讨论】:
-
您确定您的 MySQL 数据库架构是同步的吗?听起来 CpuTable.id 在数据库中没有实际的列。
-
是的,我确定。 CpuTable 是代表表“cpu”的类的名称。该表本身存在,并且其中包含“id”列。这就是我所说的,它确实存在,但是执行的语句包括“AS”指令,将 cpu.id 更改为 cpu_id。
-
确实很奇怪。试一试 mysql+mysqlconnector 以防万一。
-
我们在邮件列表中点击了这个,用户需要升级到最新的 pymysql。
-
出于某种奇怪的原因,我在这里发布了解决方案(将 pymysql 从 .4 升级到 .6),但没有发布答案
标签: python mysql sqlalchemy