[英]Get sqlalchemy base class object instead of children
I have three classes in my model, which one class inherited by the other two: 我的模型中有三个类,其中一个类由另外两个继承:
class Item(Base):
__tablename__ = 'item'
id = Column(Integer, primary_key=True)
title = Column(Unicode(300))
type = Column(Unicode(50))
__mapper_args__ = {
'polymorphic_on': type
}
class Note(Item):
__tablename__ = 'note'
id = Column(Integer, ForeignKey('item.id'), primary_key=True)
extra = Column(Text)
__mapper_args__ = {
'polymorphic_identity': 'note'
}
class Task(Item):
__tablename__ = 'task'
id = Column(Integer, ForeignKey('item.id'), primary_key=True)
another_extra = Column(Text)
__mapper_args__ = {
'polymorphic_identity': 'task'
}
So, when I execute session.query(Item).all()
I get a list that includes both Note
and Task
objects, but I don't want that, I want my objects to be the instance of Item
class and just have id
, title
, type
, not those extra fields. 所以,当我执行
session.query(Item).all()
我得到一个包含Note
和Task
对象的列表,但我不希望这样,我希望我的对象是Item
类的实例,只是有id
, title
, type
,而不是那些额外的字段。 how should I write the query? 我该怎么写这个查询?
to clarify more, currently, I get: 澄清更多,目前,我得到:
[
<models.Note object at 0x7f25ac3ffe80>,
<models.Task object at 0x7f25ac3ffe80>,
<models.Task object at 0x7f25ac3ffe80>,
...
]
But I want to get: 但我想得到:
[
<models.Item object at 0x000000000000>,
<models.Item object at 0x000000000000>,
<models.Item object at 0x000000000000>,
...
]
NOTE: This may be problematic in a multi-threaded application. 注意:这在多线程应用程序中可能存在问题。
You could use a context manager to temporarily block the polymorphism: 您可以使用上下文管理器暂时阻止多态:
from contextlib import contextmanager
from sqlalchemy import inspect
@contextmanager
def no_poly(class_):
mapper = inspect(class_).mapper
polycol = mapper.polymorphic_on
mapper.polymorphic_on = None
yield class_
mapper.polymorphic_on = polycol
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
task = Task(title='Task Title', another_extra='something')
s = Session()
s.add(task)
s.commit()
# opening a new session as if the pk already exists in the
# identity map it will return whatever type that pk is
# pointing at.
s = Session()
with no_poly(Item) as class_:
inst = s.query(class_).all()
print(inst) # [<__main__.Item object at 0x000001443685DDD8>]
s = Session() # new session again.
inst = s.query(Item).all()
print(inst) # [<__main__.Task object at 0x00000144368770B8>]
Something to be mindful of and as noted in the comments in my example, if the identity of the object is already referenced in the Identity Map , then you will get back whatever type is held in there, regardless of the class that you query on. 需要注意的事项,如我的示例中的注释中所述,如果对象的标识已在Identity Map中引用,那么无论您查询哪个类,都将返回其中的任何类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.