summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-12-04 16:58:14 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-12-04 16:58:14 -0500
commite20ac9973cbfaca77ac5884955be54d57243f94b (patch)
tree1f7587d426b0ca1caefaab54005df61f3f23559c
parentb3fa5d0326a6aa7c0fc9df08d13d849e468662a4 (diff)
downloadsqlalchemy-e20ac9973cbfaca77ac5884955be54d57243f94b.tar.gz
- update docs to declarative [ticket:2323]
-rw-r--r--doc/build/orm/relationships.rst99
1 files changed, 59 insertions, 40 deletions
diff --git a/doc/build/orm/relationships.rst b/doc/build/orm/relationships.rst
index a506fc7f3..de17c30f9 100644
--- a/doc/build/orm/relationships.rst
+++ b/doc/build/orm/relationships.rst
@@ -922,12 +922,15 @@ collection:
.. sourcecode:: python+sql
- mapper(Address, addresses_table)
- mapper(User, users_table, properties={
- 'addresses': relationship(Address, primaryjoin=
- users_table.c.user_id==addresses_table.c.user_id,
- foreign_keys=[addresses_table.c.user_id])
- })
+ class Address(Base):
+ __table__ = addresses_table
+
+ class User(Base):
+ __table__ = users_table
+ addresses = relationship(Address,
+ primaryjoin=
+ users_table.c.user_id==addresses_table.c.user_id,
+ foreign_keys=[addresses_table.c.user_id])
Building Query-Enabled Properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -942,7 +945,10 @@ conjunction with :class:`~sqlalchemy.orm.query.Query` as follows:
.. sourcecode:: python+sql
- class User(object):
+ class User(Base):
+ __tablename__ = 'user'
+ id = Column(Integer, primary_key=True)
+
def _get_addresses(self):
return object_session(self).query(Address).with_parent(self).filter(...).all()
addresses = property(_get_addresses)
@@ -953,18 +959,29 @@ Multiple Relationships against the Same Parent/Child
Theres no restriction on how many times you can relate from parent to child.
SQLAlchemy can usually figure out what you want, particularly if the join
conditions are straightforward. Below we add a ``newyork_addresses`` attribute
-to complement the ``boston_addresses`` attribute:
+to complement the ``boston_addresses`` attribute. We illustrate
+the quoted-style of configuration for ``newyork_address``, contrasted
+against the immediate Python style for ``boston_addresses``::
-.. sourcecode:: python+sql
+ class User(Base):
+ __tablename__ = 'user'
- mapper(User, users_table, properties={
- 'boston_addresses': relationship(Address, primaryjoin=
- and_(users_table.c.user_id==addresses_table.c.user_id,
- addresses_table.c.city=='Boston')),
- 'newyork_addresses': relationship(Address, primaryjoin=
- and_(users_table.c.user_id==addresses_table.c.user_id,
- addresses_table.c.city=='New York')),
- })
+ id = Column(Integer, primary_key=True)
+
+ # primaryjoin rendered as Python
+ boston_addresses = relationship(Address,
+ primaryjoin=
+ and_(id==Address.user_id,
+ Address.city=='Boston')
+ )
+
+ # primaryjoin rendered as a string which will
+ # be passed to eval()
+ newyork_addresses = relationship("Address",
+ primaryjoin=
+ "and_(User.id==Address.user_id, "
+ "Address.city=='Boston')"
+ )
.. _post_update:
@@ -1015,10 +1032,17 @@ To enable the UPDATE after INSERT / UPDATE before DELETE behavior on
:func:`~sqlalchemy.orm.relationship`, use the ``post_update`` flag on *one* of
the relationships, preferably the many-to-one side::
- mapper(Widget, widget, properties={
- 'entries':relationship(Entry, primaryjoin=widget.c.widget_id==entry.c.widget_id),
- 'favorite_entry':relationship(Entry, primaryjoin=widget.c.favorite_entry_id==entry.c.entry_id, post_update=True)
- })
+ class Widget(Base):
+ __table__ = widget_table
+
+ entries = relationship(Entry, primaryjoin=
+ widget_table.c.widget_id==
+ entry_table.c.widget_id)
+ favorite_entry = relationship(Entry,
+ primaryjoin=
+ widget_table.c.favorite_entry_id==
+ entry_table.c.entry_id,
+ post_update=True)
When a structure using the above mapping is flushed, the "widget" row will be
INSERTed minus the "favorite_entry_id" value, then all the "entry" rows will
@@ -1051,30 +1075,25 @@ conjunction with ON UPDATE CASCADE functionality,
although in that case the unit of work will be issuing
extra SELECT and UPDATE statements unnecessarily.
-A typical mutable primary key setup might look like:
+A typical mutable primary key setup might look like::
-.. sourcecode:: python+sql
-
- users = Table('users', metadata,
- Column('username', String(50), primary_key=True),
- Column('fullname', String(100)))
+ class User(Base):
+ __tablename__ = 'user'
- addresses = Table('addresses', metadata,
- Column('email', String(50), primary_key=True),
- Column('username', String(50), ForeignKey('users.username', onupdate="cascade")))
+ username = Column(String(50), primary_key=True)
+ fullname = Column(String(100))
- class User(object):
- pass
- class Address(object):
- pass
+ # passive_updates=False *only* needed if the database
+ # does not implement ON UPDATE CASCADE
+ addresses = relationship("Address", passive_updates=False)
- # passive_updates=False *only* needed if the database
- # does not implement ON UPDATE CASCADE
+ class Address(Base):
+ __tablename__ = 'address'
- mapper(User, users, properties={
- 'addresses': relationship(Address, passive_updates=False)
- })
- mapper(Address, addresses)
+ email = Column(String(50), primary_key=True)
+ username = Column(String(50),
+ ForeignKey('user.username', onupdate="cascade")
+ )
``passive_updates`` is set to ``True`` by default,
indicating that ON UPDATE CASCADE is expected to be in