脱离的SQLalchemy会话无法懒加载回溯对象
我正在尝试在 sqlalchemy 和我的 postgres 数据库之间添加一个 pylibmc 的 memcached 层。这篇文章讲了怎么做。不过我还想要反向引用(也就是在关系中从一个到多个的连接),所以我修改了那篇文章里的 user_classes.py 来测试一下。
我让 UserStatus 继承自 database.MemcachedORMObject,并在 UserTable.mapper 中添加了一个反向引用。但是当我尝试访问反向引用时,出现了“DetachedInstanceError: 父实例没有绑定到一个会话;属性 'user' 的懒加载操作无法进行”的错误。我使用的版本是 Flask-SQLAlchemy==0.16,SQLAlchemy==0.8.0b2,以及 pylibmc==1.2.3。
class UserStatus(database.MemcachedORMObject):
def __init__(self, name):
self.name = name
UserStatusTable = Table('user_status', METADATA, \
Column('user_status_id', Integer, primary_key=True),
Column('name', String) )
UserStatusTable.mapper = mapper(UserStatus, UserStatusTable)
UserStatusTable.mapper.compile()
class User(database.MemcachedORMObject):
def __init__(self, name, email, password, user_status_id):
self.name = name
self.email = email
self.password = password
self.user_status_id = user_status_id
UserTable = Table('user', METADATA, \
Column('user_id', Integer, primary_key=True),
Column('name', String),
Column('email', String),
Column('password', String),
Column('user_status_id', Integer),
ForeignKeyConstraint(['user_status_id'], ['user_status.user_status_id']) )
UserTable.mapper = mapper(User, UserTable,
properties = { 'user_status': relation(UserStatus, backref='user', lazy=False)})
UserTable.mapper.compile()
尝试访问反向引用时的错误:
In [14]: from user_classes import * In [15]: ust = UserStatus.fetch_by_field(UserStatus.user_status_id, 1) Memcached Getting: user_classes.UserStatus:(1) In [16]: ust.user
--------------------------------------------------------------------------- DetachedInstanceError Traceback (most recent call last) <ipython-input-16-38fd625abed9> in <module>()
----> 1 ust.user /home/david/sqlalchemy-memcached/env/lib/python2.7/site-packages/sqlalchemy/orm/attribut es.pyc in __get__(self, instance, owner)
249 return dict_[self.key]
250 else:
--> 251 return self.impl.get(instance_state(instance), dict_)
252
253 /home/david/sqlalchemy-memcached/env/lib/python2.7/site-packages/sqlalchemy/orm/attribut es.pyc in get(self, state, dict_, passive)
543 value = callable_(passive)
544 elif self.callable_:
--> 545 value = self.callable_(state, passive)
546 else:
547 value = ATTR_EMPTY /home/david/sqlalchemy-memcached/env/lib/python2.7/site-packages/sqlalchemy/orm/strategi es.pyc in _load_for_state(self, state, passive) 495 "Parent instance %s is not bound to a Session; "
496 "lazy load operation of attribute '%s' cannot proceed" %--> 497 (orm_util.state_str(state), self.key)
498 )
499 DetachedInstanceError: Parent instance <UserStatus at 0x21e9dd0> is not bound to a Sessi on; lazy load operation of attribute 'user' cannot proceed
1 个回答
2
这是SQLAlchemy中的一个错误。我在错误追踪系统上报告了这个问题:http://www.sqlalchemy.org/trac/ticket/2743
你总是可以沿着默认的关系方向进行操作。所以在你的情况下,一个解决办法就是改变关系的方向(这样你可以从用户状态访问用户,但反过来就不行)。
如果你以后需要双向访问,通常的解决办法是修改定义了反向引用的对象中的__dict__
属性。对于错误追踪系统中的测试案例来说,代码如下:
for p in parents:
for c in p.children:
getattr(c, '__dict__')['parent'] = p
print parents[0].children[0].parent