def create_lazy_clause(self, reverse_direction=False):
binds = util.column_dict()
- lookup = collections.defaultdict(list)
equated_columns = util.column_dict()
- if reverse_direction and self.secondaryjoin is None:
- for l, r in self.local_remote_pairs:
- lookup[r].append((r, l))
- equated_columns[l] = r
- else:
- # replace all "local side" columns, which is
- # anything that isn't marked "remote"
+ has_secondary = self.secondaryjoin is not None
+
+ if has_secondary:
+ lookup = collections.defaultdict(list)
for l, r in self.local_remote_pairs:
lookup[l].append((l, r))
equated_columns[r] = l
+ elif not reverse_direction:
+ for l, r in self.local_remote_pairs:
+ equated_columns[r] = l
+ else:
+ for l, r in self.local_remote_pairs:
+ equated_columns[l] = r
def col_to_bind(col):
- if (reverse_direction and col in lookup) or \
- (not reverse_direction and "local" in col._annotations):
- if col in lookup:
- for tobind, equated in lookup[col]:
- if equated in binds:
- return None
+
+ if (
+ (not reverse_direction and 'local' in col._annotations) or
+ reverse_direction and (
+ (has_secondary and col in lookup) or
+ (not has_secondary and 'remote' in col._annotations)
+ )
+ ):
if col not in binds:
binds[col] = sql.bindparam(
None, None, type_=col.type, unique=True)
)
)
+ def _join_fixture_remote_local_multiple_ref(self, **kw):
+ fn = lambda a, b: ((a == b) | (b == a))
+ return relationships.JoinCondition(
+ self.selfref, self.selfref,
+ self.selfref, self.selfref,
+ support_sync=False,
+ primaryjoin=fn(
+ # we're putting a do-nothing annotation on
+ # "a" so that the left/right is preserved;
+ # annotation vs. non seems to affect __eq__ behavior
+ self.selfref.c.sid._annotate({"foo": "bar"}),
+ foreign(remote(self.selfref.c.sid)))
+ )
def _assert_non_simple_warning(self, fn):
assert_raises_message(
"lft.id = :param_1 AND lft.x = :x_1",
checkparams= {'param_1': None, 'x_1': 5}
)
+
+ def test_lazy_clause_remote_local_multiple_ref(self):
+ joincond = self._join_fixture_remote_local_multiple_ref()
+ lazywhere, bind_to_col, equated_columns = joincond.create_lazy_clause()
+
+ self.assert_compile(
+ lazywhere,
+ ":param_1 = selfref.sid OR selfref.sid = :param_1",
+ checkparams={'param_1': None}
+ )
])
return sess
+ def test_descendants_lazyload_clause(self):
+ self._descendants_fixture(data=False)
+ Entity = self.classes.Entity
+ self.assert_compile(
+ Entity.descendants.property.strategy._lazywhere,
+ "entity.path LIKE (:param_1 || :path_1)"
+ )
+
+ self.assert_compile(
+ Entity.descendants.property.strategy._rev_lazywhere,
+ ":param_1 LIKE (entity.path || :path_1)"
+ )
+
+ def test_ancestors_lazyload_clause(self):
+ self._anscestors_fixture(data=False)
+ Entity = self.classes.Entity
+ # :param_1 LIKE (:param_1 || :path_1)
+ self.assert_compile(
+ Entity.anscestors.property.strategy._lazywhere,
+ ":param_1 LIKE (entity.path || :path_1)"
+ )
+
+ self.assert_compile(
+ Entity.anscestors.property.strategy._rev_lazywhere,
+ "entity.path LIKE (:param_1 || :path_1)"
+ )
+
def test_descendants_lazyload(self):
sess = self._descendants_fixture()
Entity = self.classes.Entity
)
-class CompositeSelfRefFKTest(fixtures.MappedTest):
+class CompositeSelfRefFKTest(fixtures.MappedTest, AssertsCompiledSQL):
"""Tests a composite FK where, in
the relationship(), one col points
"""
+ __dialect__ = 'default'
+
@classmethod
def define_tables(cls, metadata):
Table('company_t', metadata,
)
})
+ self._assert_lazy_clauses()
self._test()
def test_overlapping_warning(self):
)
})
+ self._assert_lazy_clauses()
self._test_no_warning()
def _test_no_overwrite(self, sess, expect_failure):
self._test_no_warning(overwrites=True)
def _test_no_warning(self, overwrites=False):
+ configure_mappers()
self._test_relationships()
sess = Session()
self._setup_data(sess)
self._test_join_aliasing(sess)
self._test_no_overwrite(sess, expect_failure=overwrites)
- def _test_relationships(self):
+ @testing.emits_warning("relationship .* will copy column ")
+ def _assert_lazy_clauses(self):
configure_mappers()
+ Employee = self.classes.Employee
+ self.assert_compile(
+ Employee.employees.property.strategy._lazywhere,
+ ":param_1 = employee_t.reports_to_id AND "
+ ":param_2 = employee_t.company_id"
+ )
+
+ self.assert_compile(
+ Employee.employees.property.strategy._rev_lazywhere,
+ "employee_t.emp_id = :param_1 AND "
+ "employee_t.company_id = :param_2"
+ )
+
+ def _test_relationships(self):
Employee = self.classes.Employee
employee_t = self.tables.employee_t
eq_(
set([
(employee_t.c.company_id, employee_t.c.company_id),
(employee_t.c.emp_id, employee_t.c.reports_to_id),
- ])
+ ])
)
eq_(
Employee.employees.property.remote_side,