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 <[email protected]> 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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.