since you are modeling a parent object with many children, but also  
with a separate many-to-one from the parent to exactly one of those  
children, you need to have a foreign key in both the node and  
noderevision table, each referencing the other table's primary key.   
You then build individual relation()s based on each of those foreign  
keys.   The relation() representing the many revisions of a Node will  
also have a "backref" on it indicating the NodeRevision belonging to a  
Node.

Then, on the latest_revision relation(), place the flag  
"post_update=True" which will indicate that a Node object should be  
added to the database using an INSERT, and then a second UPDATE after  
the child NodeRevision object has been added. This flag should be  
described in the API documentation for relation().   both relation()s  
will require a primaryjoin argument since it is ambiguous in each case  
which foreign key should be used to assemble the join.   if you wish  
to issue CREATE TABLE statements for this setup, at least one of the  
ForeignKey objects must have the flag "use_alter=True" combined with a  
"name" field so that the constraint is created after both tables exist.


On Feb 10, 2009, at 5:48 AM, Bruce van der Kooij wrote:

> Hi, this is probably extremely easy but I've only recently started  
> using
> SQLAlchemy and I simply cannot manage to model the following  
> relations:
>
> +--------------+                 +------------+
> | NodeRevision |                 | Node       |
> +--------------+  1              +------------+
> | vid          |<-------         |            |
> |              |        \      1 |            |
> |              | 1..*  --\------>| nid        |
> | nid          |<-----/   \      |            |
> |              |           \   1 |            |
> +--------------+            -----| vid        |
>                                 +------------+
>
> The diagram depicts the following relations:
>
>  * A Node has a latest_revision (Node.vid --> NodeRevision.vid)
>
>  * A Node has many revisions (Node.nid --> NodeRevision.nid)
>
>  * A NodeRevision belongs to a Node (NodeRevision.nid --> Node.nid).
>
> So far I've managed to get the following:
>
> class Node(Base):
>    __tablename__ = "node"
>
>    nid = Column(Integer, primary_key=True)
>    vid = Column(Integer, ForeignKey("node_revisions.vid"))
>
>    latest_revision = relation("NodeRevision")
>
> class NodeRevision(Base):
>    __tablename__ = "node_revisions"
>
>    vid = Column(Integer,  primary_key=True)
>    nid = Column(Integer)
>
> As you can see the only relation modeled here is the  
> Node.last_revision
> relation. Note how I've left out NodeRevision.nid = Column(Integer,
> ForeignKey(Node)) because if I add it SQLAlchemy will immediately
> complain that it needs a primaryjoin argument (and whatever I try
> nothing works).
>
> I've searched the mailing list and there were a couple of discussions
> about circular dependencies but I didn't quite understand what was  
> being
> said and how to adapt the examples to my situation.
>
> The relations most likely also need to take into account that Node
> eventually needs to have a valid vid and NodeRevision needs to have a
> valid nid. The documentation for the post_update argument on a  
> relation
> describes this situation perfectly.[1] However, as you can tell, I
> haven't even gotten that far.
>
> Any help would be greatly appreciated.
>
> Thanks.
>
> References:
>
>  [1] http://tinyurl.com/cqhk8y
>
> 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