Are you sure? I just tested it (using the definitions from the "Simplifying Association Objects" section) with the following at the bottom:
if __name__ == '__main__': user = User('log') user.keywords = [Keyword('one'), Keyword('two')] for uk in user.user_keywords: print uk, uk.user And the output was: <__main__.UserKeyword object at 0x11235910> <__main__.User object at 0x11227f50> <__main__.UserKeyword object at 0x11235a90> <__main__.User object at 0x11227f50> ie. the UserKeyword objects were associated with the user. Simon On Thu, Mar 5, 2015 at 2:30 PM, Pavel S <pa...@schon.cz> wrote: > Yes. > However doing so: > > user.keywords = [ Keyword('one'), Keyword('two') ] > > ...will create UserKeywords with user unset. This is the problem. > > > Dne čtvrtek 5. března 2015 15:11:20 UTC+1 Simon King napsal(a): >> >> I haven't looked at your code closely so I'm not sure what the problem >> is, but I'm not sure your creator factory should be necessary. The >> association proxy docs say that something like: >> >> kw = Keyword('one') >> user.keywords.append(kw) >> >> has the same effect as: >> >> kw = Keyword('one') >> uk = UserKeyword(kw) >> user.user_keywords.append(uk) >> >> In this code, the UserKeyword's "user" property is not set explicitly, >> but because of the backref on User.user_keywords, appending to the >> list will cause the "user" property to be assigned. >> >> Simon >> >> >> On Thu, Mar 5, 2015 at 11:46 AM, Pavel S <pa...@schon.cz> wrote: >> > Hi, >> > >> > I just noticed that User.groups relationship is not needed at all (it >> > was a >> > relict of previous setup before System column was added). >> > So the problem is completely gone. >> > >> > --- >> > >> > I already use AssociationProxy pattern in order to have relations like >> > User.A_groups, User.B_groups, USer.C_groups. >> > However I figured out other issue that 'creator' callback to >> > AssociationProxy does not pass the parent object to it, which is weird. >> > See example: >> > >> > user = ScopedSession.query(User).get('fred') >> > user.A_groups = [ Group('admins') ] >> > >> > It should create also intermediary instance of User2Group. It does, but >> > user >> > attribute of intermediary object is null. >> > So I created AssociationFactory as the following: >> > >> > class AssociationFactory(AssociationProxy): >> > def __init__(self, *args, **kwargs): >> > self.creator_factory = kwargs.pop('creator_factory') >> > >> > super(AssociationFactory, self).__init__(*args, **kwargs) >> > >> > >> > def __get__(self, obj, class_): >> > if obj: >> > self.creator = self.creator_factory(weakref.ref(obj)) >> > >> > return super(AssociationFactory, self).__get__(obj, class_) >> > >> > >> > for system in ('A', 'B', 'C'): >> > def creator_factory(user_ref): >> > def creator(group): >> > user = user_ref() >> > if user is None: >> > raise TypeError('Stale object reference') >> > return User2Group(user=user, group=group, system=system) >> > return creator >> > >> > setattr(User, system + '_groups', >> > AssociationFactory(system+'_users2groups', 'group', >> > creator_factory=creator_factory) >> > >> > Then all works nicely. Do you see the point? >> > cheers! >> > >> > >> > Dne čtvrtek 5. března 2015 11:58:50 UTC+1 Simon King napsal(a): >> >> >> >> Glad you've figured it out. This is touched on briefly in the docs, in >> >> the note at the bottom of: >> >> >> >> >> >> >> >> http://docs.sqlalchemy.org/en/rel_0_9/orm/basic_relationships.html#association-object >> >> >> >> As an alternative to making User.groups a relationship, you could also >> >> consider using the Association Proxy extension: >> >> >> >> >> >> >> >> http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/associationproxy.html#simplifying-association-objects >> >> >> >> Hope that helps, >> >> >> >> Simon >> >> >> >> >> >> On Thu, Mar 5, 2015 at 10:43 AM, Pavel S <pa...@schon.cz> wrote: >> >> > Hi, >> >> > Adding viewonly=True on User.groups relationship solved the issue. >> >> > cheers! >> >> > >> >> > Dne čtvrtek 5. března 2015 11:26:58 UTC+1 Pavel S napsal(a): >> >> >> >> >> >> Hello, >> >> >> >> >> >> I have relation User-User2Group-Group with additional attribute >> >> >> System >> >> >> on >> >> >> User2Group table. >> >> >> The System is part of primary key, which means 'user can me member >> >> >> of >> >> >> group via multiple systems'. >> >> >> >> >> >> class User(Base): >> >> >> __tablename__ = 'User' >> >> >> >> >> >> name = Column('Name', Unicode(256), primary_key=True) >> >> >> >> >> >> class Group(Base): >> >> >> __tablename__ = 'Group' >> >> >> >> >> >> name = Column('Name', Unicode(256), primary_key=True) >> >> >> >> >> >> class User2Group(Base): >> >> >> __tablename__ = 'User2Group' >> >> >> >> >> >> userName = Column('UserName', Unicode(256), >> >> >> ForeignKey(User.name), >> >> >> primary_key=True) >> >> >> groupName = Column('GroupName', Unicode(256), >> >> >> ForeignKey(Group.name), >> >> >> primary_key=True) >> >> >> systemName = Column('SystemName', Enum('A', 'B', 'C'), >> >> >> primary_key=True) >> >> >> >> >> >> User.groups = relationship(Group, secondary=User2Group.__table__) >> >> >> >> >> >> >> >> >> Table User2Group looks like following >> >> >> >> >> >> UserName | GroupName | SystemName >> >> >> --------------------------------- >> >> >> fred | admins | A >> >> >> fred | admins | B >> >> >> fred | admins | C >> >> >> >> >> >> >> >> >> However when trying to delete user 'fred' wich is assinged to group >> >> >> 'admins' via multiple systems A, B, C. >> >> >> >> >> >> I'm getting error: DELETE statement on table 'User2Group' expected >> >> >> to >> >> >> delete 1 row(s); Only 3 were matched. >> >> >> >> >> >> Did I misconfigured something? >> >> >> >> >> >> Thanks >> >> >> >> >> > -- >> >> > You received this message because you are subscribed to the Google >> >> > Groups >> >> > "sqlalchemy" group. >> >> > To unsubscribe from this group and stop receiving emails from it, >> >> > send >> >> > an >> >> > email to sqlalchemy+...@googlegroups.com. >> >> > To post to this group, send email to sqlal...@googlegroups.com. >> >> > Visit this group at http://groups.google.com/group/sqlalchemy. >> >> > For more options, visit https://groups.google.com/d/optout. >> > >> > -- >> > You received this message because you are subscribed to the Google >> > Groups >> > "sqlalchemy" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> > an >> > email to sqlalchemy+...@googlegroups.com. >> > To post to this group, send email to sqlal...@googlegroups.com. >> > Visit this group at http://groups.google.com/group/sqlalchemy. >> > For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.