+<%global>
+ import re
+ def format_paragraphs(text):
+ return re.sub(r'([\w ])\n([\w ])', r'\1 \2', text or '', re.S)
+</%global>
+
<%method obj_doc>
<%args>
obj
if not isclass:
if hasattr(obj, '__ALL__'):
objects = obj.__ALL__
- sort = False
+ sort = True
else:
objects = obj.__dict__.keys()
sort = True
</%init>
<&|doclib.myt:item, name=obj.__name__, description=description &>
-<&|formatting.myt:formatplain&><% obj.__doc__ %></&><br/>
+<&|formatting.myt:formatplain&><% format_paragraphs(obj.__doc__) %></&><br/>
% if not isclass and len(functions):
<&|doclib.myt:item, name="modfunc", description="Module Functions" &>
</%init>
<&| formatting.myt:function_doc, name="def " + func.__name__, arglist=argstrings &>
- <&|formatting.myt:formatplain&><% func.__doc__ %></&>
+ <&|formatting.myt:formatplain&><% format_paragraphs(func.__doc__) %></&>
</&>
</%method>
\ No newline at end of file
def __init__(self, email_address = None):
self.email_address = email_address
- mapper = assignmapper(addresses)
+ Address.mapper = mapper(Address, addresses)
# give the User class a new Mapper referencing addresses.
# "private=True" means deletions of the user
# will cascade down to the child Address objects
- User.mapper = assignmapper(users, properties = dict(
+ User.mapper = mapper(Mapper, users, properties = dict(
relation(Address.mapper, lazy=True, private=True)
))
# class definition for preferences
class UserPrefs(object):
- mapper = assignmapper(prefs)
+ pass
+ UserPrefs.mapper = mapper(UserPrefs, prefs)
# make a new mapper referencing everything.
m = mapper(User, users, properties = dict(
- addresses = relation(Address.mapper, lazy=True, private=True),
+ addresses = relation(Address, addresses, lazy=True, private=True),
preferences = relation(UserPrefs.mapper, lazy=False, private=True),
))
class Keyword(object):
def __init__(self, name = None):
self.name = name
- mapper = assignmapper(keywords)
+ Keyword.mapper = mapper(Keyword, keywords)
class Article(object):
def __init__(self):
</&>
-
- <p>Many to Many can also be done with an Association object, that adds additional information about how two items are related:</p>
+</&>
+<&|doclib.myt:item, name="association", description="Association Object" &>
+
+ <p>Many to Many can also be done with an association object, that adds additional information about how two items are related. This association object is set up in basically the same way as any other mapped object. However, since an association table typically has no primary keys, you have to tell the mapper what columns will act as its "primary keys", which are the two columns involved in the association. Also, the relation function needs an additional hint as to the fact that this mapped object is an association object, via the "association" argument which points to the class or mapper representing the other side of the association.</p>
<&|formatting.myt:code&>
# add "attached_by" column which will reference the user who attached this keyword
itemkeywords = Table('article_keywords', engine,
)
# define an association class
- class KeywordAssociation(object):pass
+ class KeywordAssociation(object):
+ pass
+
+ # mappers for Users, Keywords
+ User.mapper = mapper(User, users)
+ Keyword.mapper = mapper(Keyword, keywords)
# define the mapper. when we load an article, we always want to get the keywords via
# eager loading. but the user who added each keyword, we usually dont need so specify
# lazy loading for that.
m = mapper(Article, articles, properties=dict(
- keywords = relation(KeywordAssociation, itemkeywords, lazy = False, properties=dict(
- keyword = relation(Keyword, keywords, lazy = False),
- user = relation(User, users, lazy = True)
- )
+ keywords = relation(KeywordAssociation, itemkeywords, lazy=False, association=Keyword,
+ primary_keys = [itemkeywords.c.article_id, itemkeywords.c.keyword_id],
+ properties={
+ 'keyword' : relation(Keyword, lazy = False),
+ 'user' : relation(User, lazy = True)
+ }
)
)
)
<& pydoc.myt:obj_doc, obj=schema &>
<& pydoc.myt:obj_doc, obj=engine, classes=[engine.SQLEngine, engine.ResultProxy, engine.RowProxy] &>
<& pydoc.myt:obj_doc, obj=sql &>
-<& pydoc.myt:obj_doc, obj=pool, classes=[pool.DBProxy, pool.Pool, pool.QueuePool] &>
+<& pydoc.myt:obj_doc, obj=pool, classes=[pool.DBProxy, pool.Pool, pool.QueuePool, pool.SingletonThreadPool] &>
<& pydoc.myt:obj_doc, obj=mapper &>
<& pydoc.myt:obj_doc, obj=objectstore, classes=[objectstore.UnitOfWork] &>
</&>
\ No newline at end of file
self.echo(repr(l[0].user))
self.assert_(l[0].user is not None)
+
+ def testdouble(self):
+ """tests lazy loading with two relations simulatneously, from the same table, using aliases. """
+ openorders = alias(orders, 'openorders')
+ closedorders = alias(orders, 'closedorders')
+ m = mapper(User, users, properties = dict(
+ addresses = relation(Address, addresses, lazy = False),
+ open_orders = relation(Order, openorders, primaryjoin = and_(openorders.c.isopen == 1, users.c.user_id==openorders.c.user_id), lazy = True),
+ closed_orders = relation(Order, closedorders, primaryjoin = and_(closedorders.c.isopen == 0, users.c.user_id==closedorders.c.user_id), lazy = True)
+ ))
+ l = m.select()
+ self.assert_result(l, User,
+ {'user_id' : 7,
+ 'addresses' : (Address, [{'address_id' : 1}]),
+ 'open_orders' : (Order, [{'order_id' : 3}]),
+ 'closed_orders' : (Order, [{'order_id' : 1},{'order_id' : 5},])
+ },
+ {'user_id' : 8,
+ 'addresses' : (Address, [{'address_id' : 2}, {'address_id' : 3}]),
+ 'open_orders' : (Order, []),
+ 'closed_orders' : (Order, [])
+ },
+ {'user_id' : 9,
+ 'addresses' : (Address, []),
+ 'open_orders' : (Order, [{'order_id' : 4}]),
+ 'closed_orders' : (Order, [{'order_id' : 2}])
+ }
+ )
+
def testmanytomany(self):
"""tests a many-to-many lazy load"""
items = orderitems