考虑下面的代码创建了一个非常简单的表(不使用SQLAlchemy的),然后将使用SQLAlchemy的ORM给它的输入和检索它:奇怪的问题
import sqlite3
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
DB_PATH = '/tmp/tst.db'
#create a DB
sqlite_conn = sqlite3.connect(DB_PATH)
sqlite_conn.execute('''CREATE TABLE tst (
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
c0 INTEGER,
c1 INTEGER
);''')
sqlite_conn.commit()
#intialize an SA engine/session/mapped class
engine = create_engine('sqlite:///{}'.format(DB_PATH))
Base = declarative_base()
Base.metadata.reflect(bind=engine)
Session = sessionmaker(bind=engine)
class Tst(Base):
__table_name__ = 'tst'
__table__ = Base.metadata.tables[__table_name__]
columns = list(__table__.columns)
field_names = [c.name for c in columns]
#add an entry to the table
session = Session()
inst = Tst()
session.add(inst)
session.commit()
#retrieve an entry from the table
session = Session()
inst = session.query(Tst).first()
print inst.c1
人们可以想到的是上面的代码只会打印'无',因为'c1'没有赋值。取而代之的是,我发现了以下错误消息:
Traceback (most recent call last):
File "...", line 39, in <module>
print inst.c1
AttributeError: 'Tst' object has no attribute 'c1'
但是,如果下面一行将被删除/评论:
field_names = [c.name for c in columns]
输出将如预期。
一般来说,它看起来像类定义中的Table.columns
以上的迭代将导致从类实例中省略最后一列。
以下this answer,我实际上改变了代码使用Inspector
,它工作正常。但是,AFAIK,访问Table.columns
是完全合法的,所以我想了解它是否有问题或行为错误。
P.S.用SQLAlchemy测试1.1.9
P.P.S.这个问题似乎没有涉及到特定的DB方言 - 使用MySQL,sqlite转载。