SQLAlchemy中的性能一对多关系

时间:2017-04-27 18:28:31

标签: python 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

懒惰="动态"返回一个允许查询的列表,但我认为它很慢,并且急切地#34;因为动态关系总是查询数据库。

第二个问题:是否有一些配置可以满足我的所有需求?

3 个答案:

答案 0 :(得分:3)

您可以使用.with_parent构建lazy="dynamic"所做的同一查询。

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)

答案 1 :(得分:1)

您不需要使用类似的功能,甚至不需要在内存中加载所有子对象。
如果要搜索具有特定属性的子项,可以执行以下操作:

# 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")

答案 2 :(得分:0)

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

  • 添加lazy ="加入"你的关系,所以默认情况下,你会得到所有的父母。

  • 如果您想查询一组依赖于父项属性但不需要父对象的子项,请在查询中使用join函数并过滤引用父项和子

  • 如果您需要构建类似于lazy =" dynamic"的查询。会这样做,使用sqlalchemy.orm.defer运算符来关闭你的lazy ="加入"急切加载和loading interface(以覆盖急切加载,然后使用with_parent来构建查询。一个类似于懒惰的查询="动态"