major inefficiency in eager_defaults

Issue #3909 resolved
Mike Bayer repo owner created an issue

When "return_defaults" is used, we put all columns that are unspecified into RETURNING. However, we dont put columns that we've specified NULL for, as these are explicit in the INSERT. Then we do the SELECT, totally ruining the point of doing the RETURNING. eager_defaults should ensure that only columns that have defaults are actually in the list of columns we care about. We should not populate columns that we are explicitly passing NULL.

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    x = Column(Integer)

    __mapper_args__ = {
        "eager_defaults": True
    }

e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
Base.metadata.create_all(e)

s = Session(e)

s.add(A())
s.flush()

output:

2017-02-08 21:15:35,375 INFO sqlalchemy.engine.base.Engine INSERT INTO a (x) VALUES (%(x)s) RETURNING a.id
2017-02-08 21:15:35,375 INFO sqlalchemy.engine.base.Engine {'x': None}
2017-02-08 21:15:35,378 INFO sqlalchemy.engine.base.Engine SELECT a.x AS a_x 
FROM a 
WHERE a.id = %(param_1)s
2017-02-08 21:15:35,378 INFO sqlalchemy.engine.base.Engine {'param_1': 1}

This should likely be for 1.2.

Comments (2)

  1. Mike Bayer reporter
    • changed milestone to 1.1

    if no existing tests break then this should be good for 1.1, eager_defaults is about "defaults", not columns without any default

  2. Mike Bayer reporter

    Don't post-SELECT columns w/o a server default/onupdate for eager_defaults

    Fixed a major inefficiency in the "eager_defaults" feature whereby an unnecessary SELECT would be emitted for column values where the ORM had explicitly inserted NULL, corresponding to attributes that were unset on the object but did not have any server default specified, as well as expired attributes on update that nevertheless had no server onupdate set up. As these columns are not part of the RETURNING that eager_defaults tries to use, they should not be post-SELECTed either.

    Change-Id: I0d4f1e9d3d9717d68dcc0592f69456a1f1c36df8 Fixes: #3909

    → <<cset 000e9603065e>>

  3. Log in to comment