diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-08-28 17:57:48 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-08-28 17:57:48 -0400 |
| commit | fa5522547150687c9b3cd41d28df08ab0512b5b2 (patch) | |
| tree | 7190563b7a1c282a6b2bde3414a58a54e5e2ee56 /test/orm | |
| parent | 9f4caf97b0172065fdf0f6da8f073d72abf8fd84 (diff) | |
| download | sqlalchemy-fa5522547150687c9b3cd41d28df08ab0512b5b2.tar.gz | |
- Made a small adjustment to the mechanics of lazy loading,
such that it has less chance of interfering with a joinload() in the
very rare circumstance that an object points to itself; in this
scenario, the object refers to itself while loading its attributes
which can cause a mixup between loaders. The use case of
"object points to itself" is not fully supported, but the fix also
removes some overhead so for now is part of testing.
fixes #3145
Diffstat (limited to 'test/orm')
| -rw-r--r-- | test/orm/test_lazy_relations.py | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/test/orm/test_lazy_relations.py b/test/orm/test_lazy_relations.py index 16d14026c..e99e22725 100644 --- a/test/orm/test_lazy_relations.py +++ b/test/orm/test_lazy_relations.py @@ -2,7 +2,7 @@ from sqlalchemy.testing import assert_raises import datetime -from sqlalchemy.orm import attributes, exc as orm_exc +from sqlalchemy.orm import attributes, exc as orm_exc, configure_mappers import sqlalchemy as sa from sqlalchemy import testing, and_ from sqlalchemy import Integer, String, ForeignKey, SmallInteger, Boolean @@ -892,3 +892,81 @@ class O2MWOSideFixedTest(fixtures.MappedTest): [p.id for p in c2.people], [] ) + + +class RefersToSelfLazyLoadInterferenceTest(fixtures.MappedTest): + """Test [issue:3145]. + + This involves an object that refers to itself, which isn't + entirely a supported use case. Here, we're able to fix it, + but long term it's not clear if future needs will affect this. + The use case is not super-critical. + + """ + + @classmethod + def define_tables(cls, metadata): + Table( + 'a', metadata, + Column('a_id', Integer, primary_key=True), + Column('b_id', ForeignKey('b.b_id')), + ) + + Table( + 'b', metadata, + Column('b_id', Integer, primary_key=True), + Column('parent_id', ForeignKey('b.b_id')), + ) + + Table( + 'c', metadata, + Column('c_id', Integer, primary_key=True), + Column('b_id', ForeignKey('b.b_id')), + ) + + @classmethod + def setup_classes(cls): + class A(cls.Basic): + pass + + class B(cls.Basic): + pass + + class C(cls.Basic): + pass + + @classmethod + def setup_mappers(cls): + mapper(cls.classes.A, cls.tables.a, properties={ + "b": relationship(cls.classes.B) + }) + bm = mapper(cls.classes.B, cls.tables.b, properties={ + "parent": relationship( + cls.classes.B, remote_side=cls.tables.b.c.b_id), + "zc": relationship(cls.classes.C) + }) + mapper(cls.classes.C, cls.tables.c) + + bmp = bm._props + configure_mappers() + # Bug is order-dependent, must sort the "zc" property to the end + bmp.sort() + + def test_lazy_doesnt_interfere(self): + A, B, C = self.classes("A", "B", "C") + + session = Session() + b = B() + session.add(b) + session.flush() + + b.parent_id = b.b_id + + b.zc.append(C()) + b.zc.append(C()) + session.commit() + + # If the bug is here, the next line throws an exception + session.query(B).options( + sa.orm.joinedload('parent').joinedload('zc')).all() + |
