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 <[email protected]> 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
> > <[email protected]> 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 <[email protected]>
> >>> 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 [email protected].
> >>>> To unsubscribe from this group, send email to
> >>>> [email protected].
> >>>> 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 [email protected].
> >>> To unsubscribe from this group, send email to
> >>> [email protected].
> >>> 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 [email protected].
> >> To unsubscribe from this group, send email to
> >> [email protected].
> >> 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 [email protected].
> > To unsubscribe from this group, send email to
> > [email protected].
> > 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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.