Many thanks Michael, your instructions were spot-on. In the process of
following your instructions I decided to switch from using
ext.declarative to a non-declarative style (define tables, define
Python objects, setting up the mapping, the works :-).

Regretfully while trying to work out the rest of the model (see ASCII
diagram below) I hit another wall. I'm currently trying to make the
model Product inherit from Node, I'm having issues with this because
the situation I'm faced with deviates from the excellent examples in
the documentation.

+--------------+             +--------------+
| Node         |             | User         |
+--------------+           1 +--------------+
| nid (PK, AI) |        /--->| uid (PK, AI) |
| vid          | 0..*  /     +--------------+
| uid          |------/
+--------------+
       ^
       |
       | is subclass of
       |
+-------------+
| Product     |
+-------------+
| vid (PK)    |
| nid         |
+-------------+

The User relation is irrelevant, but I added it to present "the full
picture". I also excluded the relation with the NodeRevision model
since I already posted that above.

Creating a Product instance, adding it to the session and committing
it results in a node, a revision and a product. However the problem
that arises is that the row for the Product table will not have the
correct vid (it will remain on the default value, not with the vid of
the NodeRevision associated with the Node). Subsequent INSERTS will
then fail (duplicate entry). I'm led to believe that the problem stems
from the fact that the primary key for the products table differs from
that of the node table (vid compared to nid).

I haven't yet managed to figure out a solution to this predicament,
I'll probably look into multi-table mapping next to see if that might
help.

Here's what I've managed to get so far:

# tables.py:
node_table = Table("node", metadata,
    Column("vid", Integer, ForeignKey("node_revisions.vid")),
    Column("uid", Integer, ForeignKey("users.uid")),
    autoload=True
)

node_revisions_table = Table("node_revisions", metadata,
    Column("nid", Integer, ForeignKey("node.nid")),
    Column("uid", Integer, ForeignKey("users.uid")),
    autoload=True
)

uc_products_table = Table("uc_products", metadata,
    Column("vid", Integer, ForeignKey("node_revisions.vid"),
primary_key=True),
    Column("nid", Integer, ForeignKey("node.nid")),
    autoload=True
)

# models.py (simplified):
class Node(object):
    pass

class NodeRevision(object):
   pass

class Product(Node):
  pass

# database.py (mapping):
node_mapper = mapper(Node, node_table,
    polymorphic_on=node_table.c.type,
    properties={
        "user": relation(User),
        "latest_revision": relation(NodeRevision,
            primaryjoin=node_table.c.vid ==
node_revisions_table.c.vid,
            post_update=True
        ),
        "revisions": relation(NodeRevision,
            primaryjoin=node_table.c.nid ==
node_revisions_table.c.nid,
            backref=backref("node",
                primaryjoin=node_revisions_table.c.nid ==
node_table.c.nid
            )
        )
    }
)

node_revision_mapper = mapper(NodeRevision, node_revisions_table,
properties={
    "user": relation(User)
})

uc_products_mapper = mapper(Product, uc_products_table,
    polymorphic_identity="product"
)

# Example of creating a product (user relation left out for
simplicity):
product = Product().
product.latest_revision = NodeRevision(node=product)

Thanks for all your help.

Best regards,

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