Sqlalchemy的性能一对一关系



我正在尝试定义与sqlalchemy的一对多关系,我有很多孩子有很多孩子

class Parent(Base):
    __tablename__ = "parent"
    id = Column(String, primary_key = True)
    children = relationship("Child")

class Child(Base):
    __tablename__ = "child"
    id = Column(Integer, primary_key = True) 
    feed_type_id = Column(String, ForeignKey("parent.id"))

根据商业规则,父母没有太多孩子(10到30岁之间(,在大多数情况下,我需要访问所有孩子提高性能(第一个问题:我对吗?

def search_bar_attr(some_value)
    for bar in foo.bars:
        if(bar.attr == some_value)
            return bar

lazy ="动态"返回允许查询的列表,但我认为由于动态关系总是查询数据库而急切地与"急切的"加载。

第二个问题:是否有一些涵盖我所有需求的配置?

您可以使用lazy="dynamic"构建与CC_1相同的查询。

class Parent(Base):
    ...
    @property
    def children_dynamic(self):
        return object_session(self).query(Child).with_parent(self, Parent.children)

如果您必须写很多这些功能,甚至可以添加一个功能来减少样板:

def dynamicize(rel):
    @property
    def _getter(self):
        return object_session(self).query(rel.parent).with_parent(self, rel)
    return _getter
class Parent(Base):
    ...
    children = relationship("Child")
    children_dynamic = dynamicize(children)

您不需要使用这样的函数,甚至不需要将所有子对象加载到内存中。
当您想搜索具有一定属性的孩子时,您可以做:

# get a session object, usually with sessionmaker() configured to bind to your engine instance
c = session.query(Child).filter_by(some_attribute="some value here").all() # returns a list of all child objects that match the filter
# or: to get a child who belongs to a certain parrent with a certain attribute:
# get the parent object (p)
c = session.query(Child).filter_by(feed_type_id=p.id).filter_by(some_attr="some attribute that belongs to children of the p parrent object")

没有一个策略会为您提供一切。但是,您可以选择默认策略,然后覆盖它。我的建议是:

  • 添加懒惰="加入"到您的关系中,默认情况下,您将获得所有父母。

  • 如果您想查询一组依赖父母属性但不需要父对象的孩子的孩子,请在查询中使用JOIN功能,并指向父母和子女的过滤器

  • 在您需要构造类似于懒惰=" Dynamic"的查询的情况下,请使用sqlalchemy.orm.orm.defer操作员关闭您的懒惰=" lazy ="加入"急切的加载和加载接口(覆盖急切的加载,然后与_parent一起构建查询。像您一样懒惰的查询=" dynamic"

最新更新