From: Mike Bayer Date: Fri, 18 Nov 2005 00:13:46 +0000 (+0000) Subject: (no commit message) X-Git-Tag: rel_0_1_0~316 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f1c47d683f3f560f9084c4957c59f436def367f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git --- diff --git a/doc/build/components/pydoc.myt b/doc/build/components/pydoc.myt index cbd5e11564..8d09f8bca5 100644 --- a/doc/build/components/pydoc.myt +++ b/doc/build/components/pydoc.myt @@ -1,3 +1,9 @@ +<%global> + import re + def format_paragraphs(text): + return re.sub(r'([\w ])\n([\w ])', r'\1 \2', text or '', re.S) + + <%method obj_doc> <%args> obj @@ -12,7 +18,7 @@ if not isclass: if hasattr(obj, '__ALL__'): objects = obj.__ALL__ - sort = False + sort = True else: objects = obj.__dict__.keys() sort = True @@ -54,7 +60,7 @@ <&|doclib.myt:item, name=obj.__name__, description=description &> -<&|formatting.myt:formatplain&><% obj.__doc__ %>
+<&|formatting.myt:formatplain&><% format_paragraphs(obj.__doc__) %>
% if not isclass and len(functions): <&|doclib.myt:item, name="modfunc", description="Module Functions" &> @@ -106,6 +112,6 @@ <&| formatting.myt:function_doc, name="def " + func.__name__, arglist=argstrings &> - <&|formatting.myt:formatplain&><% func.__doc__ %> + <&|formatting.myt:formatplain&><% format_paragraphs(func.__doc__) %> \ No newline at end of file diff --git a/doc/build/content/datamapping.myt b/doc/build/content/datamapping.myt index 23316b1fdb..e3556d8dd4 100644 --- a/doc/build/content/datamapping.myt +++ b/doc/build/content/datamapping.myt @@ -325,13 +325,13 @@ WHERE users.user_name = :users_user_name ORDER BY users.oid, addresses.oid 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) )) @@ -404,11 +404,12 @@ VALUES (:address_id, :user_id, :email_address) # 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), )) @@ -479,7 +480,7 @@ VALUES (:address_id, :user_id, :email_address) 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): @@ -568,8 +569,10 @@ INSERT INTO article_keywords (article_id, keyword_id) VALUES (:article_id, :keyw - -

Many to Many can also be done with an Association object, that adds additional information about how two items are related:

+ +<&|doclib.myt:item, name="association", description="Association Object" &> + +

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.

<&|formatting.myt:code&> # add "attached_by" column which will reference the user who attached this keyword itemkeywords = Table('article_keywords', engine, @@ -579,16 +582,23 @@ INSERT INTO article_keywords (article_id, keyword_id) VALUES (:article_id, :keyw ) # 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) + } ) ) ) diff --git a/doc/build/content/docstrings.myt b/doc/build/content/docstrings.myt index 8f522218bc..b52bd55168 100644 --- a/doc/build/content/docstrings.myt +++ b/doc/build/content/docstrings.myt @@ -13,7 +13,7 @@ <& 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 diff --git a/test/mapper.py b/test/mapper.py index 989324b662..d8f84e7d65 100644 --- a/test/mapper.py +++ b/test/mapper.py @@ -139,6 +139,35 @@ class LazyTest(MapperSuperTest): 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