使用单表继承删除SQLAlchemy错误



我有一个问题与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),这就是为什么它抱怨它不能与分离对象一起工作。

最新更新