我遇到了python SQLAlchemy单表继承的问题。
型号:
class User(Base):
__tablename__ = 'user'
userID = Column(String(64), primary_key=True)
name = Column(String(64))
type = Column('type', String(50))
__mapper_args__ = {'polymorphic_on': type}
class PasswordUser(User):
__mapper_args__ = {'polymorphic_identity': 'puser'}
password = Column(String(64))
def validatePassword(self, password):
return (self.password == password)
在userManger.py中我有:
def userGet(userID):
with DBStore.Session(db) as sess:
user = sess.query(User).filter(User.userID==userID).one()
sess.expunge(user)
return user
在测试主要方法中:
myUser = userManager.userGet('123')
myUser.validatePassword("password321')
这会产生错误:
sqlalchemy.orm.exc.DetachedInstanceError:实例未绑定到会话;属性刷新操作无法继续
我已经验证myUser属于'PasswordUser'类型,并且它调用了正确的'validatePassword'方法。
奇怪的是,当我慢慢地逐步执行代码(PyDev)时,它可以正常工作。
如果我的userGet方法执行sess.query(PasswordUser),它也可以工作。但我希望这种方法是通用的,因此它可以返回任何类型的“用户”。
有什么想法吗?
答案 0 :(得分:3)
问题是当您仅查询User
,仅时,将从数据库中查询User(base)类的属性/列。为了加载子类的其他列(如password
),您需要指示query
这样做。您可以使用with_polymorphic
执行此操作,在这种情况下,您的代码可能如下所示:
def userGet(userID):
with DBStore.Session(db) as sess:
user = sess.query(User).with_polymorphic('*').filter(User.userID==userID).one()
sess.expunge(user)
return user
如果你不这样做,sqlalchemy将尝试使用会话自动加载缺少的属性(在你的情况下,password
),这就是为什么它抱怨它不能用于分离对象。< / p>