Re: [sqlalchemy] Re: many-to-many relation: unexpected count of rows
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
Re: [sqlalchemy] Re: many-to-many relation: unexpected count of rows
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+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this
Re: [sqlalchemy] Re: many-to-many relation: unexpected count of rows
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_group**s, 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 javascript: 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 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.
Re: [sqlalchemy] Re: many-to-many relation: unexpected count of rows
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+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.
Re: [sqlalchemy] Re: many-to-many relation: unexpected count of rows
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