Re: [sqlalchemy] Dynamic relations...

2011-02-13 Thread Martijn Moeling
You are right in the misunderstood relation.

I see the primary key in extra to be wrong, extra should have it's own I'd 
column being an auto number. In extra it should be possible to have many 
records pointing to 1 ext variant. Sorry for that.

The extra, should also work with tables without a discriminator, there the link 
should be made to  table name which is in my case always class.__name__ .. 
On those tables, the relation needs to be different since on of the local 
columns, discriminator is not present and it somehow should be linked to 
__table name__

It is all part of the ACL examples it talked about walker, where extra must be 
seen as the ACL. That is where the mapper extension comes in

It is getting a all technologies mixed in situation 

Verstuurd vanaf mijn iPad

Op Feb 12, 2011 om 17:05 heeft Michael Bayer mike...@zzzcomputing.com het 
volgende geschreven:

 OK I can show you the version of your code that does most of this but there 
 are some fundamental relational misunderstandings in this schema if I am 
 interpreting correctly.
 
 Extra:
 
 tableid tablename
 --- -
 1   ext1
 2   ext1
 3   ext2
 4   ext2
 5   ext3
 
 ext1:
 
 id   discriminator (- FK to Extra.tableid, Extra.tablename)
 --   -
 1ext1
 2ext1
 3ext2
 4ext2
 5ext3
 
 ext2:
 
 id
 --
 3 
 4
 
 ext3:
 
 id
 --
 
 5
 
 given ext1 ID #3, discriminator ext2 - how can more than one Extra row be 
 referenced?  Why is extras assumed to be one-to-many when it can only be 
 many-to-one ?
 
 
 
 
 
 
 On Feb 12, 2011, at 9:57 AM, Martijn Moeling wrote:
 
 This whole thing is driving me crazy, What I want:
 
 
 
 class Extra(Base):
__tablename__= extra
# Primary key consists of two different columns !!!
tableId= Column(Integer, primary_key=true)
tablename= Column(Unicode(20), primary_key=True)
 
info= Column() #Not relevant
 
 
 
 
 class ex1(Base):
   Id  = Column(Integer, primary_key=True)
   discriminator   = Column(Unicode(20))
 
   @declared_attr
   def __tablename__(self):
   return self.__name__.lower()
 
   @declared_attr
   def __mapper_args__(self):
   if self.__name__ == 'ext1':
   return {'polymorphic_on': self.discriminator, 
   'polymorphic_identity':unicode(self.__name__.lower()),
   'extension': FilePropertiesMapperExtension(),
   'batch' : False}
   else:
   return {'polymorphic_identity':unicode(self.__name__.lower()),
   'inherit_condition': self.Id == extra.Id,  
 #needed for something else in this config (multiple self reference)
   'extension': FilePropertiesMapperExtension(),  
   #Needed for something else, not relevant for this sample
   'batch' : False}   
  # ,,,,,,,,
 
 
 # Set up foreignkey and relation to Extra
   __table_args__  = (ForeignKeyConstraint(['discriminator', 'Id'], 
 ['extra.Table','extra.TableId']),{})
 
 
   extras= relation('Extra', cascade=all, lazy=dynamic 
 backref=owner)
 
 


 
 
 class ext2(ext1):
   Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
 ..
 
 
 class ext3(ext1):
   Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
 .
 
 
 
 
 Now I want:
 
 Ext2 = ext2()
 Extra_info = extra()
 Ext2.extras.append(Extra_Info)
 
 
 Ext2.discriminator should be ext2
 Ext2.Id should be 1 for the first record
 
 Extra_Info should be created in the database, with its columns : id set to 
 the Ext2.id and tablename to Ext.discriminator ..
 Extra_Info.owner would point to Ext2
 
 If Ext2 is deleted, all related extrainfo record would be delete too
 
 if one Extra_Info is deleted, Extra_Info.owner should stay in place as well 
 as all other related 
 
 Extra is many to one polymorhic version of ext1
 
 I hope this clarifies more what I want
 
 I really need the @declared_attr way of doing stuff and that is not related 
 to this question but might influence this question so I left it in..
 
 Martijn
 
 
 On Feb 10, 2011, at 18:13 , Michael Bayer wrote:
 
 
 On Feb 10, 2011, at 4:20 AM, Martijn Moeling wrote:
 
 Another small thing:
 
 I took a look at:
 
 ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 
 'invoice.ref_num'])
 
 Now for Polymorphic tables:
 
 
 in baseclass:
 
 baseclass.discriminator happens to be the __tablename__ of the polymorphic 
 
 ForeignKeyConstraint('['baseclass.disciminator', baseclass.Id'], 
 ['someotherclass.tablename','someotherclass.tableId']
 relationship('someotherclass', backref=baseclass, cascade=all, 
 

Re: [sqlalchemy] Dynamic relations...

2011-02-13 Thread Michael Bayer

On Feb 13, 2011, at 6:14 AM, Martijn Moeling wrote:

 You are right in the misunderstood relation.
 
 I see the primary key in extra to be wrong, extra should have it's own I'd 
 column being an auto number. In extra it should be possible to have many 
 records pointing to 1 ext variant. Sorry for that.
 
 The extra, should also work with tables without a discriminator, there the 
 link should be made to  table name which is in my case always class.__name__ 
 .. On those tables, the relation needs to be different since on of the 
 local columns, discriminator is not present and it somehow should be linked 
 to __table name__

OK what you are trying to do is exactly a polymorphic association.   The 
technique of placing tablename in the table of related records, then using 
that tablename to indicate which parent table should be matched at query 
time, is a common, but IMHO relationally incorrect pattern.   I blogged 
extensively about the Ruby on Rails approach, how to duplicate Rails' approach 
in SQLAlchemy, and then an alternate system which maintains referential 
integrity, four years ago at 
http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/ 
.

That's a really old example and we're into 0.7 now, so I've created a new 
version of the poly assoc example that uses declarative techniques and the 
association proxy, which is attached.  I'm going to further fix up this example 
and add it to the distribution as a fourth example of polymorphic association, 
which is in examples/poly_assoc/.

Additionally I'd like the association proxy to work more smoothly in queries so 
I've added ticket #2054 for some of those issues which weren't accounted for 
when we first added any(), contains() operators to the association proxy.





 
 It is all part of the ACL examples it talked about walker, where extra must 
 be seen as the ACL. That is where the mapper extension comes in
 
 It is getting a all technologies mixed in situation 
 
 Verstuurd vanaf mijn iPad
 
 Op Feb 12, 2011 om 17:05 heeft Michael Bayer mike...@zzzcomputing.com het 
 volgende geschreven:
 
 OK I can show you the version of your code that does most of this but there 
 are some fundamental relational misunderstandings in this schema if I am 
 interpreting correctly.
 
 Extra:
 
 tableid tablename
 --- -
 1   ext1
 2   ext1
 3   ext2
 4   ext2
 5   ext3
 
 ext1:
 
 id   discriminator (- FK to Extra.tableid, Extra.tablename)
 --   -
 1ext1
 2ext1
 3ext2
 4ext2
 5ext3
 
 ext2:
 
 id
 --
 3 
 4
 
 ext3:
 
 id
 --
 
 5
 
 given ext1 ID #3, discriminator ext2 - how can more than one Extra row be 
 referenced?  Why is extras assumed to be one-to-many when it can only be 
 many-to-one ?
 
 
 
 
 
 
 On Feb 12, 2011, at 9:57 AM, Martijn Moeling wrote:
 
 This whole thing is driving me crazy, What I want:
 
 
 
 class Extra(Base):
   __tablename__= extra
   # Primary key consists of two different columns !!!
   tableId= Column(Integer, primary_key=true)
   tablename= Column(Unicode(20), primary_key=True)
 
   info= Column() #Not relevant
 
 
 
 
 class ex1(Base):
  Id  = Column(Integer, primary_key=True)
  discriminator   = Column(Unicode(20))
 
  @declared_attr
  def __tablename__(self):
  return self.__name__.lower()
 
  @declared_attr
  def __mapper_args__(self):
  if self.__name__ == 'ext1':
  return {'polymorphic_on': self.discriminator, 
  'polymorphic_identity':unicode(self.__name__.lower()),
  'extension': FilePropertiesMapperExtension(),
  'batch' : False}
  else:
  return {'polymorphic_identity':unicode(self.__name__.lower()),
  'inherit_condition': self.Id == extra.Id,  
 #needed for something else in this config (multiple self reference)
  'extension': FilePropertiesMapperExtension(),  
   #Needed for something else, not relevant for this sample
  'batch' : False}   
  # ,,,,,,,,
 
 
 # Set up foreignkey and relation to Extra
  __table_args__  = (ForeignKeyConstraint(['discriminator', 'Id'], 
 ['extra.Table','extra.TableId']),{})
 
 
  extras= relation('Extra', cascade=all, lazy=dynamic 
 backref=owner)
 
 
   
   
 
 
 class ext2(ext1):
  Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
 ..
 
 
 class ext3(ext1):
  Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
 .
 
 
 
 
 Now I want:
 
 Ext2 = ext2()
 Extra_info = extra()
 Ext2.extras.append(Extra_Info)
 
 
 Ext2.discriminator should be ext2
 Ext2.Id should be 1 for the first 

Re: [sqlalchemy] Dynamic relations...

2011-02-13 Thread Martijn Moeling
Michael,

I looked at the code and I can not say more than that its very interesting, I 
have to see how it works and more importantly how It fits into my objects but 
it seems clear enough to do so.
I really appreciate your work on SQLAlchemy and all the time you spend to help 
us users out.

Your solution is definitively one I could not have put together myself. 
Although I have tried. SQLAlchemy is so powerful that it is hard to find the 
right options for the job.

Thank you again!

Martijn

On Feb 13, 2011, at 21:19 , Michael Bayer wrote:

 
 On Feb 13, 2011, at 6:14 AM, Martijn Moeling wrote:
 
 You are right in the misunderstood relation.
 
 I see the primary key in extra to be wrong, extra should have it's own I'd 
 column being an auto number. In extra it should be possible to have many 
 records pointing to 1 ext variant. Sorry for that.
 
 The extra, should also work with tables without a discriminator, there the 
 link should be made to  table name which is in my case always class.__name__ 
 .. On those tables, the relation needs to be different since on of the 
 local columns, discriminator is not present and it somehow should be 
 linked to __table name__
 
 OK what you are trying to do is exactly a polymorphic association.   The 
 technique of placing tablename in the table of related records, then 
 using that tablename to indicate which parent table should be matched at 
 query time, is a common, but IMHO relationally incorrect pattern.   I blogged 
 extensively about the Ruby on Rails approach, how to duplicate Rails' 
 approach in SQLAlchemy, and then an alternate system which maintains 
 referential integrity, four years ago at 
 http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/
  .
 
 That's a really old example and we're into 0.7 now, so I've created a new 
 version of the poly assoc example that uses declarative techniques and the 
 association proxy, which is attached.  I'm going to further fix up this 
 example and add it to the distribution as a fourth example of polymorphic 
 association, which is in examples/poly_assoc/.
 
 Additionally I'd like the association proxy to work more smoothly in queries 
 so I've added ticket #2054 for some of those issues which weren't accounted 
 for when we first added any(), contains() operators to the association proxy.
 
 
 
 
 
 
 It is all part of the ACL examples it talked about walker, where extra must 
 be seen as the ACL. That is where the mapper extension comes in
 
 It is getting a all technologies mixed in situation 
 
 Verstuurd vanaf mijn iPad
 
 Op Feb 12, 2011 om 17:05 heeft Michael Bayer mike...@zzzcomputing.com 
 het volgende geschreven:
 
 OK I can show you the version of your code that does most of this but there 
 are some fundamental relational misunderstandings in this schema if I am 
 interpreting correctly.
 
 Extra:
 
 tableid tablename
 --- -
 1   ext1
 2   ext1
 3   ext2
 4   ext2
 5   ext3
 
 ext1:
 
 id   discriminator (- FK to Extra.tableid, Extra.tablename)
 --   -
 1ext1
 2ext1
 3ext2
 4ext2
 5ext3
 
 ext2:
 
 id
 --
 3 
 4
 
 ext3:
 
 id
 --
 
 5
 
 given ext1 ID #3, discriminator ext2 - how can more than one Extra row be 
 referenced?  Why is extras assumed to be one-to-many when it can only be 
 many-to-one ?
 
 
 
 
 
 
 On Feb 12, 2011, at 9:57 AM, Martijn Moeling wrote:
 
 This whole thing is driving me crazy, What I want:
 
 
 
 class Extra(Base):
  __tablename__= extra
  # Primary key consists of two different columns !!!
  tableId= Column(Integer, primary_key=true)
  tablename= Column(Unicode(20), primary_key=True)
 
  info= Column() #Not relevant
 
 
 
 
 class ex1(Base):
 Id  = Column(Integer, primary_key=True)
 discriminator   = Column(Unicode(20))
 
 @declared_attr
 def __tablename__(self):
 return self.__name__.lower()
 
 @declared_attr
 def __mapper_args__(self):
 if self.__name__ == 'ext1':
 return {'polymorphic_on': self.discriminator, 
 'polymorphic_identity':unicode(self.__name__.lower()),
 'extension': FilePropertiesMapperExtension(),
 'batch' : False}
 else:
 return {'polymorphic_identity':unicode(self.__name__.lower()),
 'inherit_condition': self.Id == extra.Id,  
 #needed for something else in this config (multiple self reference)
 'extension': FilePropertiesMapperExtension(),  
   #Needed for something else, not relevant for this sample
 'batch' : False}   
  # ,,,,,,,,
 
 
 # Set up foreignkey and relation to Extra
 __table_args__  = 

Re: [sqlalchemy] Dynamic relations...

2011-02-13 Thread Michael Bayer
a polymorphic association is hard.   that's why I have three examples of them 
and soon a fourth.Though they are a subset of a larger batch of tricks 
that I've been using in my own work with declarative for the past year to 
automate lots of different kinds of patterns, perhaps there's a learning curve 
but once three or four techniques are mastered they come pretty easily.




On Feb 13, 2011, at 4:35 PM, Martijn Moeling wrote:

 Michael,
 
 I looked at the code and I can not say more than that its very interesting, I 
 have to see how it works and more importantly how It fits into my objects but 
 it seems clear enough to do so.
 I really appreciate your work on SQLAlchemy and all the time you spend to 
 help us users out.
 
 Your solution is definitively one I could not have put together myself. 
 Although I have tried. SQLAlchemy is so powerful that it is hard to find the 
 right options for the job.
 
 Thank you again!
 
 Martijn
 
 On Feb 13, 2011, at 21:19 , Michael Bayer wrote:
 
 
 On Feb 13, 2011, at 6:14 AM, Martijn Moeling wrote:
 
 You are right in the misunderstood relation.
 
 I see the primary key in extra to be wrong, extra should have it's own I'd 
 column being an auto number. In extra it should be possible to have many 
 records pointing to 1 ext variant. Sorry for that.
 
 The extra, should also work with tables without a discriminator, there the 
 link should be made to  table name which is in my case always 
 class.__name__ .. On those tables, the relation needs to be different 
 since on of the local columns, discriminator is not present and it 
 somehow should be linked to __table name__
 
 OK what you are trying to do is exactly a polymorphic association.   The 
 technique of placing tablename in the table of related records, then 
 using that tablename to indicate which parent table should be matched at 
 query time, is a common, but IMHO relationally incorrect pattern.   I 
 blogged extensively about the Ruby on Rails approach, how to duplicate 
 Rails' approach in SQLAlchemy, and then an alternate system which maintains 
 referential integrity, four years ago at 
 http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/
  .
 
 That's a really old example and we're into 0.7 now, so I've created a new 
 version of the poly assoc example that uses declarative techniques and the 
 association proxy, which is attached.  I'm going to further fix up this 
 example and add it to the distribution as a fourth example of polymorphic 
 association, which is in examples/poly_assoc/.
 
 Additionally I'd like the association proxy to work more smoothly in queries 
 so I've added ticket #2054 for some of those issues which weren't accounted 
 for when we first added any(), contains() operators to the association proxy.
 
 
 
 
 
 
 It is all part of the ACL examples it talked about walker, where extra must 
 be seen as the ACL. That is where the mapper extension comes in
 
 It is getting a all technologies mixed in situation 
 
 Verstuurd vanaf mijn iPad
 
 Op Feb 12, 2011 om 17:05 heeft Michael Bayer mike...@zzzcomputing.com 
 het volgende geschreven:
 
 OK I can show you the version of your code that does most of this but 
 there are some fundamental relational misunderstandings in this schema if 
 I am interpreting correctly.
 
 Extra:
 
 tableid tablename
 --- -
 1   ext1
 2   ext1
 3   ext2
 4   ext2
 5   ext3
 
 ext1:
 
 id   discriminator (- FK to Extra.tableid, Extra.tablename)
 --   -
 1ext1
 2ext1
 3ext2
 4ext2
 5ext3
 
 ext2:
 
 id
 --
 3 
 4
 
 ext3:
 
 id
 --
 
 5
 
 given ext1 ID #3, discriminator ext2 - how can more than one Extra row 
 be referenced?  Why is extras assumed to be one-to-many when it can only 
 be many-to-one ?
 
 
 
 
 
 
 On Feb 12, 2011, at 9:57 AM, Martijn Moeling wrote:
 
 This whole thing is driving me crazy, What I want:
 
 
 
 class Extra(Base):
 __tablename__= extra
 # Primary key consists of two different columns !!!
 tableId= Column(Integer, primary_key=true)
 tablename= Column(Unicode(20), primary_key=True)
 
 info= Column() #Not relevant
 
 
 
 
 class ex1(Base):
 Id  = Column(Integer, primary_key=True)
 discriminator   = Column(Unicode(20))
 
 @declared_attr
 def __tablename__(self):
return self.__name__.lower()
 
 @declared_attr
 def __mapper_args__(self):
if self.__name__ == 'ext1':
return {'polymorphic_on': self.discriminator, 
'polymorphic_identity':unicode(self.__name__.lower()),
'extension': FilePropertiesMapperExtension(),
'batch' : False}
else:
return {'polymorphic_identity':unicode(self.__name__.lower()),
'inherit_condition': self.Id == extra.Id,  
   

Re: [sqlalchemy] Dynamic relations...

2011-02-12 Thread Martijn Moeling
This whole thing is driving me crazy, What I want:



class Extra(Base):
__tablename__   = extra
# Primary key consists of two different columns !!!
tableId = Column(Integer, 
primary_key=true)
tablename   = Column(Unicode(20), 
primary_key=True)

info= Column() #Not 
relevant




class ex1(Base):
Id  = Column(Integer, primary_key=True)
discriminator   = Column(Unicode(20))

@declared_attr
def __tablename__(self):
return self.__name__.lower()

@declared_attr
def __mapper_args__(self):
if self.__name__ == 'ext1':
return {'polymorphic_on': self.discriminator, 
'polymorphic_identity':unicode(self.__name__.lower()),
'extension': FilePropertiesMapperExtension(),
'batch' : False}
else:
return {'polymorphic_identity':unicode(self.__name__.lower()),
'inherit_condition': self.Id == extra.Id,   
#needed for something else in this config (multiple 
self reference)
'extension': FilePropertiesMapperExtension(),   
#Needed for something else, not relevant for this sample
'batch' : False}
# ,,,,  
,,  ,,


  # Set up foreignkey and relation to Extra
__table_args__  = (ForeignKeyConstraint(['discriminator', 'Id'], 
['extra.Table','extra.TableId']),{})


extras= relation('Extra', cascade=all, lazy=dynamic 
backref=owner)






class ext2(ext1):
Id  = Column(Integer,ForeignKey('ext1.Id'), 
primary_key=True)
  ..


class ext3(ext1):
Id  = Column(Integer,ForeignKey('ext1.Id'), 
primary_key=True)
.




Now I want:

Ext2 = ext2()
Extra_info = extra()
Ext2.extras.append(Extra_Info)


Ext2.discriminator should be ext2
Ext2.Id should be 1 for the first record

Extra_Info should be created in the database, with its columns : id set to the 
Ext2.id and tablename to Ext.discriminator ..
Extra_Info.owner would point to Ext2

If Ext2 is deleted, all related extrainfo record would be delete too

if one Extra_Info is deleted, Extra_Info.owner should stay in place as well as 
all other related 

Extra is many to one polymorhic version of ext1

I hope this clarifies more what I want

I really need the @declared_attr way of doing stuff and that is not related to 
this question but might influence this question so I left it in..

Martijn


On Feb 10, 2011, at 18:13 , Michael Bayer wrote:

 
 On Feb 10, 2011, at 4:20 AM, Martijn Moeling wrote:
 
 Another small thing:
 
 I took a look at:
 
 ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 
 'invoice.ref_num'])
 
 Now for Polymorphic tables:
 
 
 in baseclass:
 
 baseclass.discriminator happens to be the __tablename__ of the polymorphic 
 
 ForeignKeyConstraint('['baseclass.disciminator', baseclass.Id'], 
 ['someotherclass.tablename','someotherclass.tableId']
 relationship('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 
 in someotheclass:
  
  tablename = column(Unicode(20), primary_key=True)
  tableId = column(Integer, primary_key=True)
 
 seems Ok to me.
 
 Now I need to make someotherclass work with non-polymorphic tables too!!
 
 anotherclass:
  Id = column(Integer, primary_key=True)
  
 ForeignKeyConstaint('[anotherclass.__tablename__,'anotherclass.Id'],['someotherclass.tablename','someotherclass.tableId'])
  relation('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 Is there any way to get this working without configuring it as polymorphic 
 an do no Inhiritance, I do not want each anotherclass record to have a 
 column discriminator with its own tablename!
 
 or can I use anotherclass.__tablename__ in the ForeignKeyConstaint?
 
 This has to do with the someotherclass being the ACL I talked about in a 
 previous post if that gives extra info. I am trying to implement the 
 MapperExtension.before_append where I need to refer to the ACL records in 
 a way like:
 
 for A in instance.ACL:
  .
 
 yeah, sorry, this use case continues to be 98% opaque to me.   I don't 
 understand what you mean by make someotherclass work with non-polymorphic 
 tables, a class is mapped in just one way, either with or without a 
 discriminator column.  A single class can't be mapped in both ways.If 
 there's no discriminator, there's just one class that can be used for 
 returned rows.
 
 If you could create a small test that illustrates a mapping and an expected 
 result, perhaps I can attempt to find a 

Re: [sqlalchemy] Dynamic relations...

2011-02-12 Thread Martijn Moeling
One more thing

Extra should also be related to other classes, not only ones setup polymorphic

Like:

class dummy(Base):
ID  = Column (Integer,Primary_key=True) 
# Set up foreignkey and relation to Extra

__table_args__  = (ForeignKeyConstraint([This tables 
tablename, 'Id'], ['extra.Table','extra.TableId']),{})
#   
^^^
extras= relation('Extra', cascade=all, lazy=dynamic 
backref=owner)

I do not really want to add a discriminator to the Dummy table for this 
relation to work

This to explain:

 yeah, sorry, this use case continues to be 98% opaque to me.   I don't 
 understand what you mean by make someotherclass work with non-polymorphic 
 tables, a class is mapped in just one way, either with or without a 
 discriminator column.  A single class can't be mapped in both ways.If 
 there's no discriminator, there's just one class that can be used for 
 returned rows.


Martijn


On Feb 12, 2011, at 15:57 , Martijn Moeling wrote:

 This whole thing is driving me crazy, What I want:
 
 
 
 class Extra(Base):
   __tablename__   = extra
   # Primary key consists of two different columns !!!
   tableId = Column(Integer, 
 primary_key=true)
   tablename   = Column(Unicode(20), 
 primary_key=True)
 
   info= Column() #Not 
 relevant
 
 
 
 
 class ex1(Base):
Id  = Column(Integer, primary_key=True)
discriminator   = Column(Unicode(20))
 
@declared_attr
def __tablename__(self):
return self.__name__.lower()
 
@declared_attr
def __mapper_args__(self):
if self.__name__ == 'ext1':
return {'polymorphic_on': self.discriminator, 
'polymorphic_identity':unicode(self.__name__.lower()),
'extension': FilePropertiesMapperExtension(),
'batch' : False}
else:
return {'polymorphic_identity':unicode(self.__name__.lower()),
'inherit_condition': self.Id == extra.Id,  
 #needed for something else in this config (multiple 
 self reference)
'extension': FilePropertiesMapperExtension(),  
 #Needed for something else, not relevant for this sample
'batch' : False}   
 # ,,,,
   ,,  ,,
 
 
  # Set up foreignkey and relation to Extra
__table_args__  = (ForeignKeyConstraint(['discriminator', 'Id'], 
 ['extra.Table','extra.TableId']),{})
 
 
extras= relation('Extra', cascade=all, lazy=dynamic 
 backref=owner)
 
 
   
   
 
 
 class ext2(ext1):
Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
  ..
 
 
 class ext3(ext1):
Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
 .
 
 
 
 
 Now I want:
 
 Ext2 = ext2()
 Extra_info = extra()
 Ext2.extras.append(Extra_Info)
 
 
 Ext2.discriminator should be ext2
 Ext2.Id should be 1 for the first record
 
 Extra_Info should be created in the database, with its columns : id set to 
 the Ext2.id and tablename to Ext.discriminator ..
 Extra_Info.owner would point to Ext2
 
 If Ext2 is deleted, all related extrainfo record would be delete too
 
 if one Extra_Info is deleted, Extra_Info.owner should stay in place as well 
 as all other related 
 
 Extra is many to one polymorhic version of ext1
 
 I hope this clarifies more what I want
 
 I really need the @declared_attr way of doing stuff and that is not related 
 to this question but might influence this question so I left it in..
 
 Martijn
 
 
 On Feb 10, 2011, at 18:13 , Michael Bayer wrote:
 
 
 On Feb 10, 2011, at 4:20 AM, Martijn Moeling wrote:
 
 Another small thing:
 
 I took a look at:
 
 ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 
 'invoice.ref_num'])
 
 Now for Polymorphic tables:
 
 
 in baseclass:
 
 baseclass.discriminator happens to be the __tablename__ of the polymorphic 
 
 ForeignKeyConstraint('['baseclass.disciminator', baseclass.Id'], 
 ['someotherclass.tablename','someotherclass.tableId']
 relationship('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 
 in someotheclass:
 
 tablename = column(Unicode(20), primary_key=True)
 tableId = column(Integer, primary_key=True)
 
 seems Ok to me.
 
 Now I need to make someotherclass work with non-polymorphic tables too!!
 
 anotherclass:
 Id = column(Integer, primary_key=True)
 
 

Re: [sqlalchemy] Dynamic relations...

2011-02-12 Thread Michael Bayer
OK I can show you the version of your code that does most of this but there are 
some fundamental relational misunderstandings in this schema if I am 
interpreting correctly.

Extra:

tableid tablename
--- -
1   ext1
2   ext1
3   ext2
4   ext2
5   ext3

ext1:

id   discriminator (- FK to Extra.tableid, Extra.tablename)
--   -
1ext1
2ext1
3ext2
4ext2
5ext3

ext2:

id
--
3 
4

ext3:

id
--

5

given ext1 ID #3, discriminator ext2 - how can more than one Extra row be 
referenced?  Why is extras assumed to be one-to-many when it can only be 
many-to-one ?






On Feb 12, 2011, at 9:57 AM, Martijn Moeling wrote:

 This whole thing is driving me crazy, What I want:
 
 
 
 class Extra(Base):
   __tablename__   = extra
   # Primary key consists of two different columns !!!
   tableId = Column(Integer, 
 primary_key=true)
   tablename   = Column(Unicode(20), 
 primary_key=True)
 
   info= Column() #Not 
 relevant
 
 
 
 
 class ex1(Base):
Id  = Column(Integer, primary_key=True)
discriminator   = Column(Unicode(20))
 
@declared_attr
def __tablename__(self):
return self.__name__.lower()
 
@declared_attr
def __mapper_args__(self):
if self.__name__ == 'ext1':
return {'polymorphic_on': self.discriminator, 
'polymorphic_identity':unicode(self.__name__.lower()),
'extension': FilePropertiesMapperExtension(),
'batch' : False}
else:
return {'polymorphic_identity':unicode(self.__name__.lower()),
'inherit_condition': self.Id == extra.Id,  
 #needed for something else in this config (multiple 
 self reference)
'extension': FilePropertiesMapperExtension(),  
 #Needed for something else, not relevant for this sample
'batch' : False}   
 # ,,,,
   ,,  ,,
 
 
  # Set up foreignkey and relation to Extra
__table_args__  = (ForeignKeyConstraint(['discriminator', 'Id'], 
 ['extra.Table','extra.TableId']),{})
 
 
extras= relation('Extra', cascade=all, lazy=dynamic 
 backref=owner)
 
 
   
   
 
 
 class ext2(ext1):
Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
  ..
 
 
 class ext3(ext1):
Id  = Column(Integer,ForeignKey('ext1.Id'), 
 primary_key=True)
 .
 
 
 
 
 Now I want:
 
 Ext2 = ext2()
 Extra_info = extra()
 Ext2.extras.append(Extra_Info)
 
 
 Ext2.discriminator should be ext2
 Ext2.Id should be 1 for the first record
 
 Extra_Info should be created in the database, with its columns : id set to 
 the Ext2.id and tablename to Ext.discriminator ..
 Extra_Info.owner would point to Ext2
 
 If Ext2 is deleted, all related extrainfo record would be delete too
 
 if one Extra_Info is deleted, Extra_Info.owner should stay in place as well 
 as all other related 
 
 Extra is many to one polymorhic version of ext1
 
 I hope this clarifies more what I want
 
 I really need the @declared_attr way of doing stuff and that is not related 
 to this question but might influence this question so I left it in..
 
 Martijn
 
 
 On Feb 10, 2011, at 18:13 , Michael Bayer wrote:
 
 
 On Feb 10, 2011, at 4:20 AM, Martijn Moeling wrote:
 
 Another small thing:
 
 I took a look at:
 
 ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 
 'invoice.ref_num'])
 
 Now for Polymorphic tables:
 
 
 in baseclass:
 
 baseclass.discriminator happens to be the __tablename__ of the polymorphic 
 
 ForeignKeyConstraint('['baseclass.disciminator', baseclass.Id'], 
 ['someotherclass.tablename','someotherclass.tableId']
 relationship('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 
 in someotheclass:
 
 tablename = column(Unicode(20), primary_key=True)
 tableId = column(Integer, primary_key=True)
 
 seems Ok to me.
 
 Now I need to make someotherclass work with non-polymorphic tables too!!
 
 anotherclass:
 Id = column(Integer, primary_key=True)
 
 ForeignKeyConstaint('[anotherclass.__tablename__,'anotherclass.Id'],['someotherclass.tablename','someotherclass.tableId'])
 relation('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 Is there any way to get this working without configuring it as polymorphic 
 an do no Inhiritance, I do not want each anotherclass record to have a 
 column discriminator with its own tablename!
 
 or can I use 

Re: [sqlalchemy] Dynamic relations...

2011-02-10 Thread Michael Bayer

On Feb 10, 2011, at 4:20 AM, Martijn Moeling wrote:

 Another small thing:
 
 I took a look at:
 
 ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 
 'invoice.ref_num'])
 
 Now for Polymorphic tables:
 
 
 in baseclass:
 
 baseclass.discriminator happens to be the __tablename__ of the polymorphic 
 
 ForeignKeyConstraint('['baseclass.disciminator', baseclass.Id'], 
 ['someotherclass.tablename','someotherclass.tableId']
 relationship('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 
 in someotheclass:
   
   tablename = column(Unicode(20), primary_key=True)
   tableId = column(Integer, primary_key=True)
 
 seems Ok to me.
 
 Now I need to make someotherclass work with non-polymorphic tables too!!
 
 anotherclass:
   Id = column(Integer, primary_key=True)
   
 ForeignKeyConstaint('[anotherclass.__tablename__,'anotherclass.Id'],['someotherclass.tablename','someotherclass.tableId'])
   relation('someotherclass', backref=baseclass, cascade=all, 
 lazy=dynamic)
 
 Is there any way to get this working without configuring it as polymorphic an 
 do no Inhiritance, I do not want each anotherclass record to have a column 
 discriminator with its own tablename!
 
 or can I use anotherclass.__tablename__ in the ForeignKeyConstaint?
 
 This has to do with the someotherclass being the ACL I talked about in a 
 previous post if that gives extra info. I am trying to implement the 
 MapperExtension.before_append where I need to refer to the ACL records in a 
 way like:
 
 for A in instance.ACL:
   .

yeah, sorry, this use case continues to be 98% opaque to me.   I don't 
understand what you mean by make someotherclass work with non-polymorphic 
tables, a class is mapped in just one way, either with or without a 
discriminator column.  A single class can't be mapped in both ways.If 
there's no discriminator, there's just one class that can be used for returned 
rows.

If you could create a small test that illustrates a mapping and an expected 
result, perhaps I can attempt to find a way to get the ORM behavior you're 
looking for.

Your mapper extension would continue to be used normally with a dynamic 
relationship since it uses query(cls) just like a regular query.



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.