gpt4 book ai didi

python - 如何使用 SQLAlchemy 根据 ID 将对象合并到 session 中,同时保持子类的正确鉴别器?

转载 作者:太空宇宙 更新时间:2023-11-03 16:56:06 24 4
gpt4 key购买 nike

我在线程之间传递对象 ID,并且希望能够通过 ID 将对象合并到 session 中。我当然可以跨线程查询对象来完成此任务,但如果对象已经在 session 中,我宁愿避免数据库访问的开销。

我的代码正在工作,但是当我由父类合并时,它没有正确设置鉴别器值。如何确保鉴别器设置正确?

from sqlalchemy import create_engine, __version__
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
from sqlalchemy.types import Integer, String

Session = scoped_session(sessionmaker())
Base = declarative_base()

class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
discriminator = Column(String, nullable=False)

__mapper_args__ = {'polymorphic_identity': 'person',
'polymorphic_on': discriminator}

class Programmer(Person):
__mapper_args__ = {'polymorphic_identity': 'programmer'}

fav_language = Column(String)

engine = create_engine('postgresql+zxjdbc://mnaber:test123@localhost:5432/ajtest2', echo=True)
Session.configure(bind=engine)
Base.metadata.bind = engine


Base.metadata.drop_all(checkfirst=True)
Base.metadata.create_all()

s = Session()
michael = Programmer(name='Michael', fav_language='Python')
s.add(michael)
s.commit()


print "Sqlalchemy Version: %s" % __version__
print "INITIAL: %s %s" % (type(michael), michael.discriminator)

michael_merged = s.merge(Person(id=michael.id)) #Merge by parent class
print "MERGED: %s %s" % (type(michael_merged), michael_merged.discriminator)
print "FINAL: %s %s" % (type(michael), michael.discriminator)

michael_merged.fav_language = 'Jython'
s.add(michael_merged)
s.commit()

有趣的输出是:

Sqlalchemy Version: 0.8.7
INITIAL: <class '__main__.Programmer'> programmer
MERGED: <class '__main__.Programmer'> person
FINAL: <class '__main__.Programmer'> person

site-packages/sqlalchemy/orm/persistence.py:154: SAWarning: Flushing object <Programmer at 0x18> with incompatible polymorphic identity 'person'; the object may not refresh and/or load correctly
mapper._validate_polymorphic_identity(mapper, state, dict_)

我应该如何确保MERGED和FINAL有程序员的鉴别器?

最佳答案

merge() 假设传入的对象看起来像您希望的那样,因此您需要在此处传递程序员。当数据库中确实存在该身份的程序员时,传入 Person(id=1) 不是受支持的模式,行为未定义。目前发生的情况是,您的 Person 对象前面设置了“person”的“鉴别器”,因此这就是刷新到数据库中的值;它会覆盖 session 中已有的内容。

你可以欺骗它像这样工作:

p1 = Person(id=michael.id)
del p1.discriminator
michael_merged = s.merge(p1) #Merge by parent class

但是,我不能保证上面的代码始终适用于 future 的 SQLAlchemy 版本。例如,它不适用于在刷新时选择“鉴别器”的早期版本。

您的代码示例是这样的,程序员已经存在于 session 中;您可以通过与类无关的方式获取此对象,如下所示:

obj = session.query(Person).get(michael.id)

然后你就有了你的 Programmer 对象,你可以自由修改它。

关于python - 如何使用 SQLAlchemy 根据 ID 将对象合并到 session 中,同时保持子类的正确鉴别器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35414057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com