you can hack this with a MapperExtension after_insert rule that sets the "account_id" field on the Person object after the "account" table is inserted. a little ugly but probably would work right now.

right now, the mapper youve made considers the primary key of of Person to be (person.id, account.id). it doenst have any notion of the join between them being synchronized.

the pattern youre using is also 99% similar to a plain inheritance pattern except you have just one class.

this would suggest that providing an external API to build up the same "synchronization" rules that joined inheritance uses could be whats needed, something along the lines of:

        mapper(Person, join(account, person), properties = {
        'id' : person.c.id,
        'handle': person.c.handle,
        'firstname': person.c.firstname,
        'lastname': person.c.lastname,
        'email_address': account.c.email_address,
        'password': account.c.password,
        }
        synchronize=[account.c.id==person.c.account_id]
        )

I think I can also get the order of "account", "person" to be sorted automatically....

On May 29, 2006, at 8:52 AM, Jamie Wilkinson wrote:

This one time, at band camp, Robin Munn wrote:
Have you looked at
http://www.sqlalchemy.org/docs/ adv_datamapping.myt#advdatamapping_joins
yet? From those docs, it looks like you should be able to simply do
"mapper(Person, join(account, person))" and have it work as you
expect, with a two-column primary key on the Person objects composed
of the primary keys of each table (account and person). In other
words, do exactly what you were trying to do, but without the
"properties = ..." part.

Yup, actually I found that right after posting.

Here's a bit more example code, with almost the same tables (few extra
fields) mapped with exactly the above mapper:

p = Person(handle='testguy', firstname='Testguy', lastname='McTest',
phone='+62195555555', email_address='[EMAIL PROTECTED]', password='test')

session.save(p)
session.flush()
pid = p.id

session.clear()
del p

p = session.get(Person, pid)
assert p is not None

This generates the following dump from the engine:

[2006-05-29 19:29:16,706] [engine]: BEGIN
[2006-05-29 19:29:16,708] [engine]: INSERT INTO account (email_address, password) VALUES (?, ?)
[2006-05-29 19:29:16,708] [engine]: ['[EMAIL PROTECTED]', 'test']
[2006-05-29 19:29:16,709] [engine]: SELECT account.id, account.email_address, account.password_hash, account.activated
FROM account
WHERE account.id = ?
[2006-05-29 19:29:16,709] [engine]: [1]
[2006-05-29 19:29:16,711] [engine]: INSERT INTO person (id, account_id, handle, firstname, lastname, phone, fax) VALUES (?, ?, ?, ?, ?, ?, ?) [2006-05-29 19:29:16,711] [engine]: [1, None, 'testguy', 'Testguy', 'McTest', '+61295555555', None]
[2006-05-29 19:29:16,712] [engine]: COMMIT
[2006-05-29 19:29:16,800] [engine]: SELECT person.fax AS person_fax, person.handle AS person_handle, person.account_id AS person_account_id, person.firstname AS person_firstname, person.lastname AS person_lastname, account.activated AS account_activated, person.phone AS person_phone, account.email_address AS account_email_address, person.id AS person_id, account.id AS account_id, account.password_hash AS account_password_hash
FROM account JOIN person ON account.id = person.account_id
WHERE account.id = ? AND person.id = ? ORDER BY account.oid
[2006-05-29 19:29:16,800] [engine]: [1, 1]

First thing to note is that the order in which the rows are entered depends entirely on the join order, i.e. person will be inserted first if the mapper
looks like mapper(Person, join(person, account)).

Second thing to note is that the account_id inserted into person is None,
not the result of the previous select that supposedly retrieves it.

Finally, the select that is retrieving the object at session.get has an extra unnecessary WHERE clause; that of account.id = ?. As we are already joining on account.id = person.account_id, this is redundant and may cause
invalid results, should person.account_id actually contain valid data.

Mike, is that enough to create a unit test?

I haven't actually tried this yet, so if you've already read those
docs and it's not working, then I don't know how to help you. But it
sure sounds from the documentation like what you're trying to do ought
to work.

Yeah ;-)


-------------------------------------------------------
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



-------------------------------------------------------
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