Hey Michael,

rev 1554 worked for me - thanks for the quick reply.

Cheers,

Nick

Michael Bayer wrote:
> Hey Nick -
> 
> I ran this test (which is well-written, youve understood the docs very
> well) with my favorite constraint checker, Postgres, and it does in fact
> fail on 0.2.1.  Fortunately, it does not fail when testing with the
> fixes I have just made today, i think its the same issue someone else
> raised today (a lot has changed with the persistence mechanism with
> regards to inheritance structures recently).  Try checking out the
> trunk, rev 1554.  also, one slight change to your program:
> 
> magazine_page_mapper = mapper(MagazinePage, magazine_page_table,
> inherits=page_mapper, polymorphic_identity='m', properties={
>     'magazine': relation(Magazine, backref=backref('pages'))
> })
> 
> and remove the extra property:
> 
> #magazine_mapper.add_property('pages', relation(MagazinePage, lazy=True,
> private=True))
> 
> this establishes 'pages' as a backreference (it will work either way if
> you are just loading the object from the DB, but the "backref" makes it
> automatically set up the two-way relationship before anything is even
> saved to the DB).
> 
> the insert order is correct including on PG which wont let constraint
> violations go by, and the output of your select at the bottom is then:
> 
> [<__main__.MagazinePage object at 0x10fea30>]
> 
> For test purposes, I threw a session.clear() right after the flush() to
> insure a full load from the DB works and i got the same result.
> 
> 
> On May 30, 2006, at 3:15 PM, Nick Joyce wrote:
> 
>> Hi,
>>
>> I am new to SQLAlchemy and have been testing it using a real-world
>> project of mine. (See attached test.py)
>>
>> I am using 0.2.1
>>
>> magazine_page.magazine_id has a foreign key to magazine.id
>>
>> Excerpt from debug.log:
>>
>> [2006-05-30 17:42:11,724] [engine]: BEGIN
>> [2006-05-30 17:42:11,724] [engine]: INSERT INTO location_name (name)
>> VALUES (?)
>> [2006-05-30 17:42:11,725] [engine]: ['London']
>> [2006-05-30 17:42:11,726] [engine]: INSERT INTO page (page_no, type)
>> VALUES (?, ?)
>> [2006-05-30 17:42:11,726] [engine]: [1, 'm']
>> [2006-05-30 17:42:11,728] [engine]: INSERT INTO magazine_page (page_id,
>> magazine_id, orders) VALUES (?, ?, ?)
>> [2006-05-30 17:42:11,728] [engine]: [1, '0', '']
>> [2006-05-30 17:42:11,729] [engine]: INSERT INTO page_size (width,
>> height, name) VALUES (?, ?, ?)
>> [2006-05-30 17:42:11,730] [engine]: [210, 297, 'A4']
>> [2006-05-30 17:42:11,731] [engine]: INSERT INTO publication (name)
>> VALUES (?)
>> [2006-05-30 17:42:11,731] [engine]: ['Test']
>> [2006-05-30 17:42:11,732] [engine]: INSERT INTO issue (publication_id,
>> issue) VALUES (?, ?)
>> [2006-05-30 17:42:11,733] [engine]: [1, 46]
>> [2006-05-30 17:42:11,734] [engine]: INSERT INTO location (issue_id, ref,
>> location_name_id) VALUES (?, ?, ?)
>> [2006-05-30 17:42:11,734] [engine]: [1, 'ABC', 1]
>> [2006-05-30 17:42:11,736] [engine]: INSERT INTO magazine (location_id,
>> page_size_id) VALUES (?, ?)
>> [2006-05-30 17:42:11,736] [engine]: [1, 1]
>> [2006-05-30 17:42:11,737] [engine]: COMMIT
>>
>> In enforcing the referential integrity shouldn't the magazine insert
>> come before the magazine_page (and update the magazine_page.magazine_id)?
>>
>> Perhaps I have the mapping wrong, if so can someone give me some
>> pointers in the right direction? I have extensively consulted the
>> documentation, but perhaps I missed something ...
>>
>> Cheers,
>>
>> Nick
>>
>>
>> [2006-05-30 17:42:11,694] [engine]: PRAGMA table_info(classified_page)
>> [2006-05-30 17:42:11,694] [engine]: {}
>> [2006-05-30 17:42:11,696] [engine]: PRAGMA table_info(magazine_page)
>> [2006-05-30 17:42:11,696] [engine]: {}
>> [2006-05-30 17:42:11,696] [engine]: PRAGMA table_info(magazine)
>> [2006-05-30 17:42:11,696] [engine]: {}
>> [2006-05-30 17:42:11,696] [engine]: PRAGMA table_info(location)
>> [2006-05-30 17:42:11,696] [engine]: {}
>> [2006-05-30 17:42:11,697] [engine]: PRAGMA table_info(location_name)
>> [2006-05-30 17:42:11,697] [engine]: {}
>> [2006-05-30 17:42:11,697] [engine]: PRAGMA table_info(issue)
>> [2006-05-30 17:42:11,697] [engine]: {}
>> [2006-05-30 17:42:11,697] [engine]: PRAGMA table_info(publication)
>> [2006-05-30 17:42:11,697] [engine]: {}
>> [2006-05-30 17:42:11,697] [engine]: PRAGMA table_info(page)
>> [2006-05-30 17:42:11,698] [engine]: {}
>> [2006-05-30 17:42:11,698] [engine]: PRAGMA table_info(page_size)
>> [2006-05-30 17:42:11,698] [engine]: {}
>> [2006-05-30 17:42:11,699] [engine]: PRAGMA table_info(page_size)
>> [2006-05-30 17:42:11,699] [engine]: {}
>> [2006-05-30 17:42:11,700] [engine]:
>> CREATE TABLE page_size(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         width INTEGER,
>>         height INTEGER,
>>         name VARCHAR(45)
>> )
>>
>>
>> [2006-05-30 17:42:11,700] [engine]: None
>> [2006-05-30 17:42:11,700] [engine]: COMMIT
>> [2006-05-30 17:42:11,701] [engine]: PRAGMA table_info(page)
>> [2006-05-30 17:42:11,701] [engine]: {}
>> [2006-05-30 17:42:11,701] [engine]:
>> CREATE TABLE page(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         page_no INTEGER,
>>         type CHAR(1)
>> )
>>
>>
>> [2006-05-30 17:42:11,702] [engine]: None
>> [2006-05-30 17:42:11,702] [engine]: COMMIT
>> [2006-05-30 17:42:11,702] [engine]: PRAGMA table_info(publication)
>> [2006-05-30 17:42:11,702] [engine]: {}
>> [2006-05-30 17:42:11,703] [engine]:
>> CREATE TABLE publication(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         name VARCHAR(45)
>> )
>>
>>
>> [2006-05-30 17:42:11,703] [engine]: None
>> [2006-05-30 17:42:11,704] [engine]: COMMIT
>> [2006-05-30 17:42:11,704] [engine]: PRAGMA table_info(issue)
>> [2006-05-30 17:42:11,704] [engine]: {}
>> [2006-05-30 17:42:11,705] [engine]:
>> CREATE TABLE issue(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         publication_id INTEGER REFERENCES publication(id),
>>         issue INTEGER
>> )
>>
>>
>> [2006-05-30 17:42:11,705] [engine]: None
>> [2006-05-30 17:42:11,705] [engine]: COMMIT
>> [2006-05-30 17:42:11,706] [engine]: PRAGMA table_info(location_name)
>> [2006-05-30 17:42:11,706] [engine]: {}
>> [2006-05-30 17:42:11,706] [engine]:
>> CREATE TABLE location_name(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         name VARCHAR(45)
>> )
>>
>>
>> [2006-05-30 17:42:11,707] [engine]: None
>> [2006-05-30 17:42:11,707] [engine]: COMMIT
>> [2006-05-30 17:42:11,707] [engine]: PRAGMA table_info(location)
>> [2006-05-30 17:42:11,707] [engine]: {}
>> [2006-05-30 17:42:11,708] [engine]:
>> CREATE TABLE location(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         issue_id INTEGER REFERENCES issue(id),
>>         ref CHAR(3),
>>         location_name_id INTEGER REFERENCES location_name(id)
>> )
>>
>>
>> [2006-05-30 17:42:11,708] [engine]: None
>> [2006-05-30 17:42:11,709] [engine]: COMMIT
>> [2006-05-30 17:42:11,709] [engine]: PRAGMA table_info(magazine)
>> [2006-05-30 17:42:11,709] [engine]: {}
>> [2006-05-30 17:42:11,710] [engine]:
>> CREATE TABLE magazine(
>>         id INTEGER NOT NULL PRIMARY KEY,
>>         location_id INTEGER REFERENCES location(id),
>>         page_size_id INTEGER REFERENCES page_size(id)
>> )
>>
>>
>> [2006-05-30 17:42:11,710] [engine]: None
>> [2006-05-30 17:42:11,711] [engine]: COMMIT
>> [2006-05-30 17:42:11,711] [engine]: PRAGMA table_info(magazine_page)
>> [2006-05-30 17:42:11,711] [engine]: {}
>> [2006-05-30 17:42:11,712] [engine]:
>> CREATE TABLE magazine_page(
>>         page_id INTEGER NOT NULL PRIMARY KEY REFERENCES page(id),
>>         magazine_id INTEGER REFERENCES magazine(id),
>>         orders TEXT
>> )
>>
>>
>> [2006-05-30 17:42:11,712] [engine]: None
>> [2006-05-30 17:42:11,713] [engine]: COMMIT
>> [2006-05-30 17:42:11,713] [engine]: PRAGMA table_info(classified_page)
>> [2006-05-30 17:42:11,713] [engine]: {}
>> [2006-05-30 17:42:11,714] [engine]:
>> CREATE TABLE classified_page(
>>         magazine_page_id INTEGER NOT NULL PRIMARY KEY REFERENCES
>> magazine_page(page_id),
>>         titles VARCHAR(45)
>> )
>>
>>
>> [2006-05-30 17:42:11,714] [engine]: None
>> [2006-05-30 17:42:11,714] [engine]: COMMIT
>> [2006-05-30 17:42:11,718] [engine]: SELECT location_name.id AS
>> location_name_id, location_name.name AS location_name_name
>> FROM location_name
>> WHERE location_name.name = ? ORDER BY location_name.oid
>>  LIMIT 1 OFFSET 0
>> [2006-05-30 17:42:11,718] [engine]: ['London']
>> [2006-05-30 17:42:11,724] [engine]: BEGIN
>> [2006-05-30 17:42:11,724] [engine]: INSERT INTO location_name (name)
>> VALUES (?)
>> [2006-05-30 17:42:11,725] [engine]: ['London']
>> [2006-05-30 17:42:11,726] [engine]: INSERT INTO page (page_no, type)
>> VALUES (?, ?)
>> [2006-05-30 17:42:11,726] [engine]: [1, 'm']
>> [2006-05-30 17:42:11,728] [engine]: INSERT INTO magazine_page
>> (page_id, magazine_id, orders) VALUES (?, ?, ?)
>> [2006-05-30 17:42:11,728] [engine]: [1, '0', '']
>> [2006-05-30 17:42:11,729] [engine]: INSERT INTO page_size (width,
>> height, name) VALUES (?, ?, ?)
>> [2006-05-30 17:42:11,730] [engine]: [210, 297, 'A4']
>> [2006-05-30 17:42:11,731] [engine]: INSERT INTO publication (name)
>> VALUES (?)
>> [2006-05-30 17:42:11,731] [engine]: ['Test']
>> [2006-05-30 17:42:11,732] [engine]: INSERT INTO issue (publication_id,
>> issue) VALUES (?, ?)
>> [2006-05-30 17:42:11,733] [engine]: [1, 46]
>> [2006-05-30 17:42:11,734] [engine]: INSERT INTO location (issue_id,
>> ref, location_name_id) VALUES (?, ?, ?)
>> [2006-05-30 17:42:11,734] [engine]: [1, 'ABC', 1]
>> [2006-05-30 17:42:11,736] [engine]: INSERT INTO magazine (location_id,
>> page_size_id) VALUES (?, ?)
>> [2006-05-30 17:42:11,736] [engine]: [1, 1]
>> [2006-05-30 17:42:11,737] [engine]: COMMIT
>> import sqlalchemy.mods.threadlocal
>> from sqlalchemy import *
>>
>> # set-up tables
>>
>> metadata = BoundMetaData('sqlite://:memory:')
>>
>> publication_table = Table('publication', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('name', String(45), default=''),
>> )
>> issue_table = Table('issue', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('publication_id', Integer, ForeignKey('publication.id'),
>> default='0'),
>>     Column('issue', Integer, default='0'),
>> )
>> location_table = Table('location', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('issue_id', Integer, ForeignKey('issue.id'), default='0'),
>>     Column('ref', CHAR(3), default=''),
>>     Column('location_name_id', Integer,
>> ForeignKey('location_name.id'), default='0'),
>> )
>> location_name_table = Table('location_name', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('name', String(45), default=''),
>> )
>> magazine_table = Table('magazine', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('location_id', Integer, ForeignKey('location.id'),
>> default='0'),
>>     Column('page_size_id', Integer, ForeignKey('page_size.id'),
>> default='0'),
>> )
>> page_table = Table('page', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('page_no', Integer, default='0'),
>>     Column('type', CHAR(1), default='p'),
>> )
>> magazine_page_table = Table('magazine_page', metadata,
>>     Column('page_id', Integer, ForeignKey('page.id'),
>> primary_key=True, default='0'),
>>     Column('magazine_id', Integer, ForeignKey('magazine.id'),
>> default='0'),
>>     Column('orders', TEXT, default=''),
>> )
>> classified_page_table = Table('classified_page', metadata,
>>     Column('magazine_page_id', Integer,
>> ForeignKey('magazine_page.page_id'), primary_key=True, default='0'),
>>     Column('titles', String(45), default=''),
>> )
>> page_size_table = Table('page_size', metadata,
>>     Column('id', Integer, primary_key=True, default=None),
>>     Column('width', Integer, default='0'),
>>     Column('height', Integer, default='0'),
>>     Column('name', String(45), default=''),
>> )
>>
>> # mapping objects
>>
>> class BaseObject(object):
>>     def __init__(self, *args, **kwargs):
>>         for key, value in kwargs.iteritems():
>>             setattr(self, key, value)
>>
>> class Publication(BaseObject):
>>     pass
>>
>> class Issue(BaseObject):
>>     pass
>>
>> class Location(BaseObject):
>>     def _get_name(self):
>>         return self._name
>>
>>     def _set_name(self, name):
>>         session = objectstore.get_session()
>>         s =
>> session.query(LocationName).selectfirst(location_name_table.c.name==name)
>>
>>         if s is not None:
>>             self._name = s
>>
>>             return
>>
>>         found = False
>>
>>         for i in session.new:
>>             if isinstance(i, LocationName) and i.name == name:
>>                 self._name = i
>>                 found = True
>>
>>                 break
>>
>>         if found == False:
>>             self._name = LocationName(name=name)
>>
>>     name = property(_get_name, _set_name)
>>
>> class LocationName(BaseObject):
>>     pass
>>
>> class PageSize(BaseObject):
>>     pass
>>
>> class Magazine(BaseObject):
>>     pass
>>
>> class Page(BaseObject):
>>     pass
>>
>> class MagazinePage(Page):
>>     def __init__(self, *args, **kwargs):
>>         Page.__init__(self, *args, **kwargs)
>>
>> class ClassifiedPage(MagazinePage):
>>     pass
>>
>> # define mapping
>>
>> publication_mapper = mapper(Publication, publication_table)
>>
>> issue_mapper = mapper(Issue, issue_table, properties = {
>>     'publication': relation(Publication, backref=backref('issues',
>> cascade="add, delete-orphan")),
>> })
>>
>> location_name_mapper = mapper(LocationName, location_name_table)
>>
>> location_mapper = mapper(Location, location_table, properties = {
>>     'issue': relation(Issue, backref='locations'),
>>     '_name': relation(LocationName),
>> })
>>
>> issue_mapper.add_property('locations', relation(Location, lazy=False,
>> private=True, backref='issue'))
>>
>> page_size_mapper = mapper(PageSize, page_size_table)
>>
>> page_join = polymorphic_union(
>>     {
>>         'm': page_table.join(magazine_page_table),
>>         'p': page_table.select(page_table.c.type=='p'),
>>     }, None, 'page_join')
>>
>> magazine_mapper = mapper(Magazine, magazine_table, properties = {
>>     'location': relation(Location, backref=backref('magazine',
>> uselist=False)),
>>     'size': relation(PageSize),
>> })
>>
>> page_mapper = mapper(Page, page_table, select_table=page_join,
>> polymorphic_on=page_join.c.type, polymorphic_identity='p')
>>
>> magazine_page_mapper = mapper(MagazinePage, magazine_page_table,
>> inherits=page_mapper, polymorphic_identity='m', properties={
>>     'magazine': relation(Magazine)
>> })
>>
>> magazine_mapper.add_property('pages', relation(MagazinePage,
>> lazy=True, private=True))
>>
>> #classified_page_mapper = mapper(ClassifiedPage,
>> classified_page_table, inherits=MagazinePage.mapper,
>> polymorphic_identity='c')
>>
>> session = objectstore.get_session()
>>
>> # do some operations
>>
>> metadata.engine.echo = True
>>
>> # metadata.drop_all()
>> metadata.create_all()
>>
>> pub = Publication(name='Test')
>> issue = Issue(issue=46,publication=pub)
>> location = Location(ref='ABC',name='London',issue=issue)
>>
>> page_size = PageSize(name='A4',width=210,height=297)
>>
>> magazine = Magazine(location=location,size=page_size)
>>
>> page = MagazinePage(magazine=magazine,page_no=1)
>>
>> session.flush()
>>
>> '''
>> p = session.query(Publication).selectone_by(name='Test')
>>
>> print p.issues[0].locations[0].magazine.pages
>> '''
> 
> 
> 
> -------------------------------------------------------
> All the advantages of Linux Managed Hosting--Without the Cost and Risk!
> Fully trained technicians. The highest number of Red Hat certifications in
> the hosting industry. Fanatical Support. Click to learn more
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642



-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to