Re: [sqlalchemy] Re: many-to-many relation: unexpected count of rows

2015-03-05 Thread Simon King
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

2015-03-05 Thread Simon King
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

2015-03-05 Thread Pavel S
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

2015-03-05 Thread Simon King
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

2015-03-05 Thread Pavel S
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