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.

Reply via email to