- marked as critical
make a reasonable assumption about primary/secondary with m2m
if foreign_keys is specified with "secondary", emit a warning. because, why are they doing that.
then, remove most mention of "foreign_keys" from these messages - the ForeignKeys should be on table metadata. don't encourage working around it.
then, do this:
diff -r 252ab17c7dc5f1cfd1a5173fb6d9e4b819e1ebb7 lib/sqlalchemy/orm/properties.py
--- a/lib/sqlalchemy/orm/properties.py Fri Aug 13 14:25:58 2010 -0400
+++ b/lib/sqlalchemy/orm/properties.py Fri Aug 13 14:26:42 2010 -0400
@@ -1023,6 +1023,16 @@
self.synchronize_pairs.append((l, r))
elif l in self._foreign_keys:
self.synchronize_pairs.append((r, l))
+ elif self.secondary is not None:
+ fks = self._foreign_keys or set(self.secondary.c)
+ eq_pairs = criterion_as_pairs(self.primaryjoin,
+ consider_as_foreign_keys=fks,
+ any_operator=self.viewonly)
+ eq_pairs = [r) for (l, r) in eq_pairs
+ if self._col_is_part_of_mappings(l)
+ and self._col_is_part_of_mappings(r)
+ or self.viewonly and r in fks]((l,)
+ self.synchronize_pairs = eq_pairs
else:
eq_pairs = criterion_as_pairs(self.primaryjoin,
consider_as_foreign_keys=self._foreign_keys,
@@ -1063,13 +1073,14 @@
"foreign." % (self.primaryjoin, self))
self.synchronize_pairs = eq_pairs
if self.secondaryjoin is not None:
+ fks = self._foreign_keys or set(self.secondary.c)
sq_pairs = criterion_as_pairs(self.secondaryjoin,
- consider_as_foreign_keys=self._foreign_keys,
+ consider_as_foreign_keys=fks,
any_operator=self.viewonly)
sq_pairs = [r) for (l, r) in sq_pairs
if self._col_is_part_of_mappings(l)
and self._col_is_part_of_mappings(r) or r
- in self._foreign_keys]((l,)
+ in fks]
if not sq_pairs:
if not self.viewonly \
and criterion_as_pairs(self.secondaryjoin,
try to find any possible weird setup where the foreign keys collection shouldn't be limited to the secondary table. It certainly wasn't meant to work any other way. We should not have anyone confused by things like this.
Comments (4)
-
reporter -
reporter it seems so far like it's impossible anyone is making usage of "secondary" with fks on the other side. the test below fails for both the persistence and the query side, hitting codepaths that are assuming fks are on "secondary". trace out these paths to ensure this is the case.
from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import * Base = declarative_base() metadata = Base.metadata assoc = Table('assoc', metadata, Column('id1', Integer, primary_key=True), Column('id2', Integer, primary_key=True) ) class Foo(Base): __tablename__ ='foo' id = Column(Integer, primary_key=True) assoc_id = Column(Integer, ForeignKey('assoc.id1')) bars = relationship("Bar", secondary=assoc) class Bar(Base): __tablename__ ='bar' id = Column(Integer, primary_key=True) assoc_id = Column(Integer, ForeignKey('assoc.id2')) compile_mappers() engine = create_engine('sqlite://', echo=True) metadata.create_all(engine) session = sessionmaker(engine)() # doesn't work session.execute(assoc.insert().values(id1=1, id2=1)) f1 = Foo(assoc_id=1) f1.bars = [Bar(assoc_id=1)](Bar(assoc_id=1),) session.add(f1) session.commit() session.execute(assoc.insert().values(id1=1, id2=1)) session.execute(Foo.__table__.insert().values(id=1, assoc_id=1)) session.execute(Bar.__table__.insert().values(id=1, assoc_id=1)) # doens't work f = session.query(Foo).first() print f.bars
-
reporter - changed status to resolved
this is in 8fc50cd3a4eb98501c5ae47ead07c20b485934df
-
reporter - removed milestone
Removing milestone: 0.6.4 (automated comment)
- Log in to comment