Python 在SQLALchemy中,在一对一的关系中进行了太多的选择

Python 在SQLALchemy中,在一对一的关系中进行了太多的选择,python,sql,database,performance,sqlalchemy,Python,Sql,Database,Performance,Sqlalchemy,当我尝试使用一对一关系访问链访问某些对象时,即使不需要进行查询,我也会在每个点操作中获得一个SELECT 看看代码。当我尝试获取对象“bla”时,SQLAlchemy生成3个查询: import sqlalchemy as db from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.ext.declarative import declarative_base Base = declarative_base(

当我尝试使用一对一关系访问链访问某些对象时,即使不需要进行查询,我也会在每个点操作中获得一个SELECT

看看代码。当我尝试获取对象“bla”时,SQLAlchemy生成3个查询:

import sqlalchemy as db
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Entity(Base):
    __tablename__ = 'entity'
    id = db.Column(db.Integer, primary_key=True, index=True)
    a = db.Column(db.Integer, index=True)
    b = db.Column(db.Integer)

    foos = relationship('Foo')


class Foo(Base):
    __tablename__ = 'foo'
    id = db.Column(db.Integer, primary_key=True, index=True)

    entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'))

    entity = relationship('Entity', uselist=False)
    bars = relationship('Bar')


class Bar(Base):
    __tablename__ = 'bar'
    id = db.Column(db.Integer, primary_key=True, index=True)

    foo_id = db.Column(db.Integer, db.ForeignKey('foo.id'))

    foo = relationship('Foo', uselist=False)

engine = db.create_engine('sqlite:///:memory:', echo=False)
session = sessionmaker(bind=engine)()
Base.metadata.create_all(engine)

def relationship_optimizing():
    engine.echo = True
    entity = Entity(a=1000000, b=10000000000)
    foo = Foo(entity=entity)
    bar = Bar(foo=foo)
    session.add_all([entity, foo, bar])
    session.commit()
    bla = session.query(Entity).filter_by(id=bar.foo.entity_id).one()
    session.commit()

relationship_optimizing()
我尝试在所有关系中使用lazy=“joined”和lazy=“subquery”,但前两个查询仍然存在。我想摆脱他们。最终查询可以使用联接,但它应该是唯一一个查询

这是一个有趣的例子,但在实际项目中,当我只访问Relationship字段时,有太多类似的寄生虫查询。
我的项目执行了大量的小查询(大部分是一条记录),因此性能非常慢:(

问题是,您在调用
add\u all
后正在提交。提交后,SQLAlchemy无法知道其他事务没有修改与您的对象对应的行,因此它“忘记了”它们的所有属性,直到下次使用它们为止

在你的工作中没有理由提交,它确实首先破坏了事务的目的。如果你需要做的就是在你的对象上填充<代码> ID <代码>,使用<代码> session .FrHuSH()/代码>,它更新数据库以匹配你的对象——不提交.< /P>


session.commit()
只能解决此问题,因为它(必须)首先刷新,但由于某些原因,当您需要的只是自动键时,提交而不是刷新已成为一个虚构的建议。

谢谢。您能否提供更多的示例,说明何时应该刷新会话而不是提交会话?何时需要提交?例如,我有一个用户可以执行服务连接、收费等操作n、 当前,在每次用户操作后,我都会提交。我应该只在程序退出后提交吗?提交比刷新慢吗?当您希望一批工作作为单个单元成功或失败时,您应该提交。因此,一个用户操作可能存在于一个事务中,是的。否则,如果以后出现问题,部分数据已经更改,但不是全部,现在您的数据可能处于错误状态。
SELECT bar.id AS bar_id, bar.foo_id AS bar_foo_id 
FROM bar 
WHERE bar.id = 1

SELECT foo.id AS foo_id, foo.entity_id AS foo_entity_id 
FROM foo 
WHERE foo.id = 1

SELECT entity.id AS entity_id, entity.a AS entity_a, entity.b AS entity_b 
FROM entity 
WHERE entity.id = 1