【问题标题】:SQLAlchemy with single table inheritance expunge error具有单表继承删除错误的 SQLAlchemy
【发布时间】:2023-03-30 13:53:02
【问题描述】:

我遇到了 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),它也可以工作。但我希望这个方法是通用的,所以它可以返回任何类型的“用户”。

有什么想法吗?

【问题讨论】:

    标签: python inheritance sqlalchemy


    【解决方案1】:

    问题在于,当您仅查询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),这就是为什么它抱怨它不能使用分离的对象。

    【讨论】:

    • 谢谢!像魅力一样工作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    相关资源
    最近更新 更多