<&|doclib.myt:item, name="inheritance", description="Mapping a Class with Table Inheritance" &>
- <p>Table Inheritance indicates the pattern where two tables, in a parent-child relationship, are mapped to an inheritance chain of classes. If a table "news_articles" contains additional information about sports articles in the table "sports_news_articles", a corresponding object inheritance pattern would have a NewsArticle class and a SportsNewsArticle class. Loading a SportsNewsArticle object means you are joining sports_news_articles to news_articles. For SQLAlchemy, this pattern is just a special case of a mapper that maps against a joined relationship, and is provided via the <span class="codeline">inherits</span> keyword.
+ <p>Table Inheritance indicates the pattern where two tables, in a parent-child relationship, are mapped to an inheritance chain of classes. If a table "employees" contains additional information about managers in the table "mangaers", a corresponding object inheritance pattern would have an Employee class and a Manager class. Loading a Mangaer object means you are joining managers to employees. For SQLAlchemy, this pattern is just a special case of a mapper that maps against a joined relationship, and is provided via the <span class="codeline">inherits</span> keyword.
<&|formatting.myt:code&>
class User(object):
"""a user object."""
pass
# define a mapper for AddressUser that inherits the User.mapper, and joins on the user_id column
- # inherit_condition is required right now, but will be optional in a future release
AddressUser.mapper = mapper(
addresses, inherits=User.mapper
)
pass
# define a Join
- # the join condition will be optional in a future release if foreign keys are defined
- j = join(users, addresses, users.c.address_id==addresses.c.address_id)
+ j = join(users, addresses)
# map to it - the identity of an AddressUser object will be
# based on (user_id, address_id) since those are the primary keys involved
<p>In this case, with the private flag set, the element that was removed from the addresses list was also removed from the database. By specifying the <span class="codeline">private</span> flag on a relation, it is indicated to the Mapper that these related objects exist only as children of the parent object, otherwise should be deleted.</p>
</&>
<&|doclib.myt:item, name="backreferences", description="Useful Feature: Backreferences" &>
-<p>By creating relations with the <span class="codeline">backreference</span> keyword, a bi-directional relationship can be created which will keep both ends of the relationship updated automatically, even without any database queries being executed. Below, the User mapper is created with an "addresses" property, and the corresponding Address mapper receives a "backreference" to the User object via the property name "user":
+<p>By creating relations with the <span class="codeline">backref</span> keyword, a bi-directional relationship can be created which will keep both ends of the relationship updated automatically, even without any database queries being executed. Below, the User mapper is created with an "addresses" property, and the corresponding Address mapper receives a "backreference" to the User object via the property name "user":
<&|formatting.myt:code&>
User.mapper = mapper(User, users, properties = {
- 'addresses' : relation(Address, addresses, backreference='user')
+ 'addresses' : relation(Address, addresses, backref='user')
}
)
Address.mapper = mapper(Address, addresses)
User.mapper = mapper(User, users, properties = {
- 'addresses' : relation(Address.mapper, backreference='user')
+ 'addresses' : relation(Address.mapper, backref='user')
}
)
Address.mapper.add_property('user', relation(
- User.mapper, lazy=False, private=True, backreference='addresses'
+ User.mapper, lazy=False, private=True, backref='addresses'
))
</&>
<p>The standard set of generic types are:</p>
<&|formatting.myt:code&>
# sqlalchemy.types package:
-class String: pass
-class Integer: pass
-class Numeric: pass
-class DateTime: pass
-class Binary: pass
-class Boolean: pass
+class String(TypeEngine):
+ def __init__(self, length=None)
+
+class Integer(TypeEngine)
+
+class Numeric(TypeEngine):
+ def __init__(self, precision=10, length=2)
+
+class Float(TypeEngine):
+ def __init__(self, precision=10)
+
+class DateTime(TypeEngine)
+
+class Binary(TypeEngine):
+ def __init__(self, length=None)
+
+class Boolean(TypeEngine)
</&>
<p>More specific subclasses of these types are available, to allow finer grained control over types:</p>
<&|formatting.myt:code&>
-class FLOAT(Numeric):pass
-class TEXT(String):pass
-class DECIMAL(Numeric):pass
-class INT(Integer):pass
+class FLOAT(Numeric)
+class TEXT(String)
+class DECIMAL(Numeric)
+class INT(Integer)
INTEGER = INT
-class TIMESTAMP(DateTime): pass
-class DATETIME(DateTime): pass
-class CLOB(String): pass
-class VARCHAR(String): pass
-class CHAR(String):pass
-class BLOB(Binary): pass
-class BOOLEAN(Boolean): pass
+class TIMESTAMP(DateTime)
+class DATETIME(DateTime)
+class CLOB(String)
+class VARCHAR(String)
+class CHAR(String)
+class BLOB(Binary)
+class BOOLEAN(Boolean)
</&>
<p>When using a specific database engine, these types are adapted even further via a set of database-specific subclasses defined by the database engine.</p>
</&>