I made a type in the Right model, here are the models again:

class HasSomeAttribute(object):
    @declared_attr.cascading
    def type(cls):
       if has_inherited_table(cls):
           if cls.__name__ == 'MySubClass1':
               return db.Column(db.Integer, default=1)
           else:
               return db.Column(db.Integer, default=2)
       else:
           return db.Column(db.Integer, default=0)
       
class MyClass(HasSomeAttribute, db.Model):
   __tablename__ = 'people4l2'
   id = db.Column(db.Integer, primary_key=True)
    id1 = db.Column(db.Integer)
    id2 = db.Column(db.Integer)

class MySubClass1(MyClass):
   pass
   
class MySubClass2(MyClass):
   pass

class Right(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    left = relationship(
       'Left',
       secondary= MySubClass1.__table__,
       primaryjoin='and_(MySubClass1.type == 802, MySubClass1.id2 == 
Right.id)',
       secondaryjoin='and_(MySubClass1.type == 802, MySubClass1.id1 == 
Left.id)'
   )

class Left(db.Model):
    id = db.Column(db.Integer, primary_key=True)


On Tuesday, March 31, 2015 at 12:12:35 PM UTC+2, Pierre B wrote:
>
> Hi Michael,
>
> Thank you for your response.
> Unfortunately I have already tried to use the __init__ function/catch the 
> init event but I am only referencing the sub classes in a relationship 
> which does not seem to actually instantiate classes because the __init__ is 
> never called/init event is never fired.
> Here is a simple version of my models.
>
> class HasSomeAttribute(object):
>     @declared_attr.cascading
>     def type(cls):
>         if has_inherited_table(cls):
>             if cls.__name__ == 'MySubClass1':
>                 return db.Column(db.Integer, default=1)
>             else:
>                 return db.Column(db.Integer, default=2)
>         else:
>             return db.Column(db.Integer, default=0)
>         
> class MyClass(HasSomeAttribute, db.Model):
>     __tablename__ = 'people4l2'
>     id = db.Column(db.Integer, primary_key=True)
>     id1 = db.Column(db.Integer)
>     id2 = db.Column(db.Integer)
>
> class MySubClass1(MyClass):
>     pass
>     
> class MySubClass2(MyClass):
>     pass
>
> class Right(db.Model):
>     id = db.Column(db.Integer, primary_key=True)
>     subclass_attr = relationship(
>         'Contact',
>         secondary= MySubClass1.__table__,
>         primaryjoin='and_(MySubClass1.type == 802, MySubClass1.id2 == 
> Right.id)',
>         secondaryjoin='and_(MySubClass1.type == 802, MySubClass1.id1 == 
> Left.id)'
>     )
>
> class Left(db.Model):
>     id = db.Column(db.Integer, primary_key=True)
>
> MyClass is used as a junction table for a bunch of different 
> relationships, the type field is used to differentiate the relationships.
>
>
> On Monday, March 30, 2015 at 5:26:30 PM UTC+2, Michael Bayer wrote:
>>
>>
>>
>> Pierre B <rocambol...@gmail.com> wrote: 
>>
>> > Hi all, 
>> > 
>> > I'm ultimately trying to have different default values for the same 
>> column. Following the documentation, the @declared_attr.cacading decorator 
>> seems to be the best approach. 
>> > Here's my code: 
>> > class HasSomeAttribute(object): 
>> >     @declared_attr.cascading 
>> >     def type(cls): 
>> >         if has_inherited_table(cls): 
>> >             if cls.__name__ == 'MySubClass1': 
>> >                 return db.Column(db.Integer, default=1) 
>> >             else: 
>> >                 return db.Column(db.Integer, default=2) 
>> >         else: 
>> >             return db.Column(db.Integer, default=0) 
>> >         
>> > class MyClass(HasSomeAttribute, db.Model): 
>> >     __tablename__ = 'people4l2' 
>> >     id = db.Column(db.Integer, primary_key=True) 
>> > 
>> > class MySubClass1(MyClass): 
>> >     pass 
>> >     
>> > class MySubClass2(MyClass): 
>> >     pass 
>> > 
>> > I iterated quite a few times over this but I'm systematically getting 
>> this error: 
>> > ArgumentError: Column 'type' on class <class '__main__.MySubClass1'> 
>> conflicts with existing column 'people4l2.type’ 
>>
>> this mapping illustrates MySubClass1 and MySubClass2 as both sharing the 
>> same table “people4l2”, as they have no __tablename__ attribute, so there 
>> can only be one “type” column. So in this case it is not appropriate to 
>> use 
>> cascading in exactly this way, as MyClass already has a “type” column, 
>> and 
>> that gets attached to the “people4l2” table and that’s it; there can be 
>> no 
>> different “type” column on MySubClass1/MySubClass2. 
>>
>> If you’d like “type” to do something different based on which class is 
>> being 
>> instantiated, this is an ORM-level differentiation. Use either the 
>> constructor __init__() to set it or use the init() event 
>> (
>> http://docs.sqlalchemy.org/en/rel_0_9/orm/events.html?highlight=event%20init#sqlalchemy.orm.events.InstanceEvents.init).
>>  
>>
>>
>> OTOH if “type” is actually the “polymoprhic discriminator”, which is what 
>> this looks like, then you’d be looking to just set up “type” as the 
>> “polymorphic_on” column and set up the “1”, “2”, “0” as the polymorphic 
>> identity (see 
>>
>> http://docs.sqlalchemy.org/en/rel_0_9/orm/inheritance.html#single-table-inheritance
>>  
>> for a simple example). 
>>
>>

-- 
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