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 <javascript:>> 
> 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 <javascript:>. 
> > To post to this group, send email to sqlal...@googlegroups.com 
> <javascript:>. 
> > 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.

Reply via email to