这是一个项目的一部分,该项目涉及使用 tg2 处理其中的 2 个数据库(该模型使用的是 mssql)。因为我需要读取/写入的表是使用不同的应用程序创建和管理的,所以我不希望 turbogears 覆盖/更改表 - 只需使用现有表 - 所以我使用 sqlalchemy 神奇的“自动加载”反射(我也不知道 mssql db 中这个表配置的每个细节model.__init__.py
)由于 tg2 内部工作,一些反射是在课堂上而不是在课堂上完成的(正如一些 sqlalchemy 教程所建议的那样)
这是我收到的错误消息:(数据库中的表名是 SOMETABLE,在我的应用程序中,类是活动)
sqlalchemy.exc.ArgumentError: Mapper Mapper|Activities|SOMETABLE could not
assemble any primary key columns for mapped table 'SOMETABLE'
这是活动课:
class Activities(DeclarativeBase2):
__tablename__ = 'SOMETABLE'
#tried the classic way, I used in another place without tg but didn't work here - the reflection should be outside the class
#__table_args__= {'autoload':True
#,'autoload_with':engine2
#}
def __init__(self,**kw):
for k,v in kw.items():
setattr(self,k,v)
这是model.__init__.py
初始化模型方法(调用反射的地方):
def init_model(engine1,engine2):
"""Call me before using any of the tables or classes in the model."""
DBSession.configure(bind=engine1)
DBSession2.configure(bind=engine2)
# If you are using reflection to introspect your database and create
# table objects for you, your tables must be defined and mapped inside
# the init_model function, so that the engine is available if you
# use the model outside tg2, you need to make sure this is called before
# you use the model.
#
# See the following example:
metadata.bind = engine1
metadata2.bind = engine2
#metadata2=MetaData(engine2)
global t_reflected
#
t_reflected = Table("SOMETABLE", metadata2,
autoload=True, autoload_with=engine2)
#
mapper(Activities, t_reflected
所以我想我需要告诉 sqlalchemy 什么是主键 - 但是在使用反射时我该怎么做(我知道主键字段)?
编辑工作解决方案:
def init_model(engine1,engine2):
"""Call me before using any of the tables or classes in the model."""
DBSession.configure(bind=engine1)
DBSession2.configure(bind=engine2)
# If you are using reflection to introspect your database and create
# table objects for you, your tables must be defined and mapped inside
# the init_model function, so that the engine is available if you
# use the model outside tg2, you need to make sure this is called before
# you use the model.
#
# See the following example:
metadata.bind = engine1
metadata2.bind = engine2
#metadata2=MetaData(engine2)
global t_reflected
#
t_reflected = Table("SOMETABLE", metadata2,String,primary_key=True),
autoload=True, autoload_with=engine2)# adding the primary key column here didn't work
#
mapper(Activities, t_reflected, non_primary=True)# notice the needed non_primary - for some reason I can't do the whole mapping in one file and I Have to do part in init_model and part in the model - quite annoying
同样在模型中,我必须添加主键列:
class Activities(DeclarativeBase2):
__tablename__ = 'SOMETABLE'
#tried the classic way, I used in another place without tg but didn't work here - the reflection should be outside the class
EVENTCODE = Column(String, primary_key=True)# needed because the reflection couldn't find the primary key .
当然,我还必须添加各种导入model.__init__.py
来完成这项工作
奇怪的是,它甚至在连接到数据库之前抱怨没有找到主键,并且当一个独立的 sqlalchemy 类(没有 tg2)执行相同的键时 - 根本没有抱怨。让你想知道