Thank you for your fast reply and bug fix. I will test this tonight.

Cheers,

Julien.

On Tue, Sep 28, 2010 at 6:46 PM, Michael Bayer <mike...@zzzcomputing.com> wrote:
> this is a bug, ticket #1930, fixed in r36755ba72782.   Note that a similar 
> issue exists for joined table inheritance, and a scheme like the below will 
> continue to fail if __tablename__ is added to subclasses (this is ticket 
> #1931).   The specific "scheme" is that the attribute name of the column in 
> the mixin does not match the column name itself.
>
> http://www.sqlalchemy.org/trac/ticket/1930
> http://www.sqlalchemy.org/trac/ticket/1931
>
>
>
> On Sep 28, 2010, at 12:06 PM, Julien Iguchi-Cartigny wrote:
>
>> Hello Michael,
>>
>> Sorry I missing something but still trap in this problem.
>>
>> As far as I am:
>>
>> class AbstractContainer(Base,AbstractNamed):
>>    __tablename__ = 'CM_MEMBER_CONTAINER_T'
>>    id = Column('MEMBER_CONTAINER_ID',Integer,primary_key=True)
>>    discriminator = Column('CLASS_DISCR', String(100))
>>    __mapper_args__ = {'polymorphic_on': discriminator }
>>
>> class CourseSet(AbstractContainer):
>>
>>   �...@classproperty
>>    def __mapper_args__(self):
>>        args = dict()
>>        args.update(AbstractContainer.__mapper_args__)
>>        args.update({'polymorphic_identity':
>> 'org.sakaiproject.coursemanagement.impl.CourseSetCmImpl'})
>>        return args
>>
>> The inheritance pass is : Course <- AbstractContainer <- AbstractNamed
>> <- AbstractPersistence  (see my first email for the definitions of the
>> last two classes).
>>
>> Still having some trouble:
>>
>> sqlalchemy.exc.ArgumentError: Column 'VERSION' on class <class
>> '__main__.CourseSet'> conflicts with existing column
>> 'CM_MEMBER_CONTAINER_T.VERSION'
>>
>> It I understand correctly, AbstractContainer has already mapped all
>> columns declared in parent classes. So CourseSet tries to remap
>> everything (it herits from Base) but it fails because all column are
>> already mapped.
>>
>> So I must say something like "hey, let just reuse mapping and table
>> definitions from AbstractContainer" but how can i do this ?
>>
>> It seems it is very simple from the POV of the documentation, so I
>> must deduce the problem comes from the multiple inheritance.
>>
>> Cheers,
>>
>> Julien.
>>
>> PS: This is the full listing of my code:
>>
>> from sqlalchemy import create_engine, Column, String, Date, Integer
>> from sqlalchemy.orm import sessionmaker
>> from sqlalchemy.ext.declarative import declarative_base
>> from sqlalchemy.ext.declarative import has_inherited_table
>> from sqlalchemy.util import classproperty
>>
>> engine = create_engine(
>>    'mysql://xxx:y...@localhost:3306/zzz?charset=utf8&use_unicode=0',
>>    pool_recycle=3600, echo=True)
>>
>> Base = declarative_base()
>>
>> class AbstractPersistent(object):
>>    version = Column('VERSION', Integer)
>>    last_modified_by = Column('LAST_MODIFIED_BY', String(255))
>>    last_modified_date = Column('LAST_MODIFIED_DATE', Date)
>>    created_by = Column('CREATED_BY', String(255))
>>    created_date = Column('CREATED_DATE', Date)
>>
>>    def __repr__(self):
>>        return "<AbstractPersistent('%s','%s', '%s','%s','%s')>" % \
>>            (self.version, self.last_modified_by,
>> self.last_modified_date,
>>            self.created_by, self.created_date)
>>
>> class AbstractNamed(AbstractPersistent):
>>    eid = Column('ENTERPRISE_ID', String(255))
>>    title = Column('TITLE', String(255))
>>    description = Column('DESCRIPTION', String(255))
>>
>>    def __repr__(self):
>>        return "<AbstractNamed('%s','%s', '%s')>" % \
>>            (self.eid, self.title, self.description) + \
>>                super(AbstractNamed, self).__repr__()
>>
>> class AbstractContainer(Base,AbstractNamed):
>>    __tablename__ = 'CM_MEMBER_CONTAINER_T'
>>    id = Column('MEMBER_CONTAINER_ID',Integer,primary_key=True)
>>    discriminator = Column('CLASS_DISCR', String(100))
>>    __mapper_args__ = {'polymorphic_on': discriminator }
>>
>> class AcademicSession(Base,AbstractNamed):
>>    __tablename__ = 'CM_ACADEMIC_SESSION_T'
>>    id = Column('ACADEMIC_SESSION_ID',Integer,primary_key=True)
>>    start_date = Column('START_DATE', Date)
>>    end_date = Column('END_DATE', Date)
>>
>>    def __repr__(self):
>>        return "<AcademicSession('%s','%s', '%s')>" % \
>>            (self.id, self.start_date, self.end_date) + \
>>            super(AcademicSession, self).__repr__()
>>
>> class CourseSet(AbstractContainer):
>>
>>   �...@classproperty
>>    def __mapper_args__(self):
>>        args = dict()
>>        args.update(AbstractContainer.__mapper_args__)
>>        args.update({'polymorphic_identity':
>> 'org.sakaiproject.coursemanagement.impl.CourseSetCmImpl'})
>>        return args
>>
>> if __name__ == "__main__":
>>    Session = sessionmaker(bind=engine)
>>    session = Session()
>>    academic_sessions = session.query(AcademicSession).all()
>>    print(academic_sessions)
>>    course_sets = session.query(CourseSet).all()
>>    print(course_sets)
>>
>>
>>
>> On 27 sep, 23:55, Michael Bayer <mike...@zzzcomputing.com> wrote:
>>> On Sep 27, 2010, at 5:10 PM, Julien Iguchi-Cartigny wrote:
>>>
>>>> But How can i do ? It seems i need to define the table in
>>>> AsbtractContainer but every time I've an error about already defined
>>>> column.
>>>
>>> Your original setup seems as though you'd like both CourseSet and 
>>> CanonicalCourse to be mapped to the same table using single table 
>>> inheritance.   Therefore they both must extend a class that is mapped to 
>>> the target table.   So in this case you'd like AbstractContainer to be 
>>> mapped, meaning the "Base" superclass should be moved from CourseSet and 
>>> CanonicalCourse onto AbstractContainer.
>>>
>>> You can then query for AbstractContainer subclasses using 
>>> session.query(AbstractContainer).
>>>
>>>
>>>
>>>
>>>
>>>> Cheers,
>>>
>>>> Julien.
>>>
>>>> On Mon, Sep 27, 2010 at 10:30 PM, Michael Bayer
>>>> <mike...@zzzcomputing.com> wrote:
>>>
>>>>> On Sep 27, 2010, at 4:21 PM, Julien Iguchi-Cartigny wrote:
>>>
>>>>>> Thank you Michael. This solves the problem and... shows a new one.
>>>
>>>>>> So this is my update CourseSet
>>>
>>>>>>  class CourseSet(Base,AbstractContainer):
>>>
>>>>>>     �...@classproperty
>>>>>>      def __mapper_args__(self):
>>>>>>          args = dict()
>>>>>>          args.update(AbstractContainer.__mapper_args__)
>>>>>>          args.update({'polymorphic_identity':
>>>>>> 'org.sakaiproject.coursemanagement.impl.CourseSetCmImpl'})
>>>>>>          return args
>>>
>>>>>> Because there is several discriminant values, I need to create other 
>>>>>> ones:
>>>
>>>>>> class CanonicalCourse(Base,AbstractContainer):
>>>
>>>>>>   �...@classproperty
>>>>>>    def __mapper_args__(self):
>>>>>>        args = dict()
>>>>>>        args.update(AbstractContainer.__mapper_args__)
>>>>>>        args.update({'polymorphic_identity':
>>>>>> 'org.sakaiproject.coursemanagement.impl.CanonicalCourseCmImpl'})
>>>>>>        return args
>>>
>>>>>> But this last one will fail, i've the following error message:
>>>
>>>>>> sqlalchemy.exc.InvalidRequestError: Table 'CM_MEMBER_CONTAINER_T' is
>>>>>> already defined for this MetaData instance.  Specify
>>>>>> 'useexisting=True' to redefine options and columns on an existing
>>>>>> Table object.
>>>
>>>>>> I could use useexisting=True but i don't know if it's the right
>>>>>> solution. Any ideas ?
>>>
>>>>> that has to do with a Table() statement, or alternatively how you are 
>>>>> configuring __table_name__, neither of which are indicated here, so you 
>>>>> need to ensure that distinct table names are used whenever a table name 
>>>>> is declared.
>>>
>>>>>> Cheers,
>>>
>>>>>> Julien.
>>>
>>>>>> On Mon, Sep 27, 2010 at 1:02 AM, Michael Bayer 
>>>>>> <mike...@zzzcomputing.com> wrote:
>>>
>>>>>>> On Sep 26, 2010, at 6:38 PM, Julien Iguchi-Cartigny wrote:
>>>
>>>>>>>> Hi,
>>>
>>>>>>>> I'm trying to use polymorphic_on with several inheritances:
>>>
>>>>>>>>    engine = create_engine(
>>>>>>>>        
>>>>>>>> 'mysql://xxx:y...@localhost:3306/zzz?charset=utf8&use_unicode=0',
>>>>>>>>        pool_recycle=3600, echo=True)
>>>
>>>>>>>>    Base = declarative_base()
>>>
>>>>>>>>    class AbstractPersistent(object):
>>>>>>>>        version = Column('VERSION', Integer)
>>>>>>>>        last_modified_by = Column('LAST_MODIFIED_BY', String(255))
>>>>>>>>        last_modified_date = Column('LAST_MODIFIED_DATE', Date)
>>>>>>>>        created_by = Column('CREATED_BY', String(255))
>>>>>>>>        created_date = Column('CREATED_DATE', Date)
>>>
>>>>>>>>    class AbstractNamed(AbstractPersistent):
>>>>>>>>        eid = Column('ENTERPRISE_ID', String(255))
>>>>>>>>        title = Column('TITLE', String(255))
>>>>>>>>        description = Column('DESCRIPTION', String(255))
>>>
>>>>>>>>    class AbstractContainer(AbstractNamed):
>>>>>>>>        __tablename__ = 'CM_MEMBER_CONTAINER_T'
>>>>>>>>        id = Column('MEMBER_CONTAINER_ID',Integer,primary_key=True)
>>>>>>>>        discriminator = Column('CLASS_DISCR', String(100))
>>>>>>>>        __mapper_args__ = {'polymorphic_on': discriminator }
>>>
>>>>>>>>    class CourseSet(Base,AbstractContainer):
>>>>>>>>        __mapper_args__ = {'polymorphic_identity':
>>>>>>>> 'org.sakaiproject.coursemanagement.impl.CourseSetCmImpl'}
>>>
>>>>>>> AbstractContainer is not mapped, its a mixin, so its __mapper_args__ 
>>>>>>> are not used until a subclass of Base is invoked, which starts up a 
>>>>>>> declarative mapping.  Your only mapped class then is CourseSet, which 
>>>>>>> has its own __mapper_args__ , that override those of AbstractContainer 
>>>>>>> - they are ignored.
>>>
>>>>>>> To combine __mapper_args__ from a mapped class with those of a mixin, 
>>>>>>> see the example 
>>>>>>> athttp://www.sqlalchemy.org/docs/orm/extensions/declarative.html?highli....
>>>>>>>   It uses __table_args__ but the same concept of creating a full 
>>>>>>> dictionary of arguments applies for __mapper_args__ as well.
>>>
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>> Groups "sqlalchemy" group.
>>>>>>> To post to this group, send email to sqlalch...@googlegroups.com.
>>>>>>> To unsubscribe from this group, send email to 
>>>>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>>>>> For more options, visit this group 
>>>>>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>>>
>>>>>> --
>>>>>> "Trouble-a-cat limited"
>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "sqlalchemy" group.
>>>>>> To post to this group, send email to sqlalch...@googlegroups.com.
>>>>>> To unsubscribe from this group, send email to 
>>>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>>>> For more options, visit this group 
>>>>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google Groups 
>>>>> "sqlalchemy" group.
>>>>> To post to this group, send email to sqlalch...@googlegroups.com.
>>>>> To unsubscribe from this group, send email to 
>>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>>> For more options, visit this group 
>>>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>>>
>>>> --
>>>> "Trouble-a-cat limited"
>>>
>>>> --
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "sqlalchemy" group.
>>>> To post to this group, send email to sqlalch...@googlegroups.com.
>>>> To unsubscribe from this group, send email to 
>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>> For more options, visit this group 
>>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "sqlalchemy" group.
>> To post to this group, send email to sqlalch...@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.
>>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@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.
>
>



-- 
"Trouble-a-cat limited"

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@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.

Reply via email to