OK. I've found the bug. In my UnionCalendar, I called the children,
calendars, which didn't match the name in the mappers.
It works, and here is a one file cut down version
from sqlalchemy import create_engine
from sqlalchemy import Table, Integer, Column, Boolean, String, MetaData,
ForeignKey
from sqlalchemy.orm import mapper, sessionmaker, relationship
class Entity (object):
pass
class Calendar (Entity):
'''
Calendar to contain holiday dates
'''
def __init__ (self, code, name):
self.code = code
self.name = name
def isholiday (self, when):
'''
Is when a holiday in the calendar?
'''
pass
class SimpleCalendar (Calendar):
'''
Calendar with name 'name'
'''
def isholiday (self, when):
return False
def __repr__ (self):
res = "<%s('%s', %s, %s, %s, %s, %s, %s, %s, '%s')>\n" % \
(
self.__class__.__name__,
self.code,
self.name
)
return res
class UnionCalendar (Calendar):
'''
A union of more than two calendars
'''
def __init__ (self, cals):
Calendar.__init__(self, " ".join ([cal.code for cal in cals]), " - ".join
([cal.name for cal in cals]))
self.children = cals
def isholiday (self, when):
for cal in self.children:
if cal.isholiday (when):
return True
return False
def __repr__ (self):
return "<UnionCalendar (%s)>\n" % ", ".join ([cal.code for cal in
self.children])
engine = create_engine('sqlite:///:memory:', echo=True)
metadata = MetaData()
Session = sessionmaker(bind=engine)
session = Session()
calendars_table = Table \
(
'calendars',
metadata,
Column ('id', Integer, primary_key=True),
Column ('code', String, nullable=False, unique=True),
Column ('name', String),
Column ('calendar_type', String (20), nullable=False)
)
calendar_children_table = Table \
(
'calendar_children',
metadata,
Column ('parent_id', Integer, ForeignKey ('calendars.id')),
Column ('child_id', Integer, ForeignKey ('calendars.id'))
)
calendar_mapper = \
mapper \
(
Calendar,
calendars_table,
polymorphic_on=calendars_table.c.calendar_type,
polymorphic_identity="calendar"
)
simple_calendar_mapper = \
mapper \
(
SimpleCalendar,
inherits=calendar_mapper,
polymorphic_identity='simple'
)
union_calendar_mapper = \
mapper \
(
UnionCalendar,
inherits=calendar_mapper,
polymorphic_identity='union',
properties = \
{
'children':relationship \
(
Calendar,
secondary=calendar_children_table,
primaryjoin = calendar_children_table.c.parent_id == calendars_table.c.id,
secondaryjoin = calendar_children_table.c.child_id == calendars_table.c.id
)
}
)
metadata.create_all (engine)
ny = SimpleCalendar(code='NY',name='New York')
lon = SimpleCalendar(code='LON',name='London')
session.add (ny)
session.add (lon)
session.commit()
uc = UnionCalendar ([ny, lon])
print uc
print 'add'
session.add (uc)
session.flush()
session.commit()
print 'done'
for c in uc.children:
print c.code
Thanks for your help Michael.
If you need a generic example for the docs, I'll write it up.
On , Michael Bayer <mike...@zzzcomputing.com> wrote:
On Mar 31, 2011, at 6:26 AM, Nick Leaton wrote:
> OK, still one problem. It's not saving the association object.
>
> Here is the code
>
> ===================================
> from sqlalchemy import create_engine
> from sqlalchemy import Table, Integer, Column, Boolean, String,
MetaData, ForeignKey
> from sqlalchemy.orm import mapper, sessionmaker, relationship
>
> from Entities.Calendar import Calendar
> from Entities.SimpleCalendar import SimpleCalendar
> from Entities.UnionCalendar import UnionCalendar
> from Entities.Holiday import Holiday
> from Entities.SimpleHoliday import SimpleHoliday
> from Entities.RepeatingHoliday import RepeatingHoliday
>
>
> ny = SimpleCalendar(code='NY',name='New
York',holidays=[SimpleHoliday("New Year", 2011,1,1)])
> lon =
SimpleCalendar(code='LON',name='London',holidays=[SimpleHoliday("New
Year", 2011,1,1),RepeatingHoliday('MayDay',5,1)])
> session.add (ny)
> session.add (lon)
> session.commit()
> uc = UnionCalendar ([ny, lon])
> print uc
> print 'add'
> session.add (uc)
> session.flush()
So I'd need to see where you are populating "children". I don't see that
in the example here (if it is happening, I assume the constructor of
UnionCalendar is doing it somehow) so that would be why nothing gets put
into calendar_children.
if you inline the classes themselves into the test then you'd have an
example others can reproduce.
--
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.
--
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.