我有一个问题与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)
在usermanager .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),它也可以工作。但是我希望这个方法是通用的,所以它可以返回任何类型的'User'。
任何想法?
问题是,当您只查询User
时,只有从数据库中查询User(基)类的属性/列。为了为子类加载其他列(如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
),这就是为什么它抱怨它不能与分离对象一起工作。