root / elixir / tags / 0.6.0 / tests / test_o2m.py

Revision 362, 5.4 kB (checked in by ged, 4 years ago)
  • Added support for callables for some arguments on relationships:
    primaryjoin, secondaryjoin and remote_side. It means those can be evaluated
    at setup time (when tables and their columns already exist) instead of
    definition time (closes #50).
  • Misc cleanup
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1"""
2test one to many relationships
3"""
4
5from elixir import *
6from sqlalchemy import and_
7from sqlalchemy.ext.orderinglist import ordering_list
8
9def setup():
10    metadata.bind = 'sqlite:///'
11
12class TestOneToMany(object):
13    def teardown(self):
14        cleanup_all(True)
15
16    def test_simple(self):
17        class A(Entity):
18            name = Field(String(60))
19            bs = OneToMany('B')
20
21        class B(Entity):
22            name = Field(String(60))
23            a = ManyToOne('A')
24
25        setup_all(True)
26
27        a1 = A(name='a1')
28        b1 = B(name='b1', a=a1)
29
30        # does it work before a commit? (does the backref work?)
31        assert b1 in a1.bs
32
33        session.commit()
34        session.clear()
35
36        b = B.query.one()
37        a = b.a
38
39        assert b in a.bs
40
41    def test_selfref(self):
42        class Person(Entity):
43            name = Field(String(30))
44
45            father = ManyToOne('Person', inverse='children')
46            children = OneToMany('Person', inverse='father')
47
48        setup_all(True)
49
50        grampa = Person(name="Abe")
51        homer = Person(name="Homer")
52        bart = Person(name="Bart")
53        lisa = Person(name="Lisa")
54
55        grampa.children.append(homer)
56        homer.children.append(bart)
57        lisa.father = homer
58
59        session.commit()
60        session.clear()
61
62        p = Person.get_by(name="Homer")
63
64        print "%s is %s's child." % (p.name, p.father.name)
65        print "His children are: %s." % (
66                " and ".join([c.name for c in p.children]))
67
68        assert p in p.father.children
69        assert p.father is Person.get_by(name="Abe")
70        assert p is Person.get_by(name="Lisa").father
71
72    def test_multiple_selfref(self):
73        # define a self-referential table with several relations
74
75        class TreeNode(Entity):
76            name = Field(String(50), required=True)
77
78            parent = ManyToOne('TreeNode')
79            children = OneToMany('TreeNode', inverse='parent')
80            root = ManyToOne('TreeNode')
81
82            def __str__(self):
83                return self._getstring(0)
84
85            def _getstring(self, level):
86                s = '  ' * level + \
87                    "%s (%s,%s,%s, %d)" % (self.name, self.id, self.parent_id,
88                                           self.root_id, id(self)) + \
89                    '\n'
90                s += ''.join([n._getstring(level+1) for n in self.children])
91                return s
92
93        setup_all(True)
94
95        node2 = TreeNode(name='node2')
96        node2.children.append(TreeNode(name='subnode1'))
97        node2.children.append(TreeNode(name='subnode2'))
98        node = TreeNode(name='rootnode')
99        node.children.append(TreeNode(name='node1'))
100        node.children.append(node2)
101        node.children.append(TreeNode(name='node3'))
102
103        session.commit()
104        session.clear()
105
106        root = TreeNode.get_by(name='rootnode')
107        print root
108
109    def test_viewonly(self):
110        class User(Entity):
111            two_blurbs = OneToMany('Blurb', primaryjoin=lambda:
112                and_(Blurb.user_id == User.id, Blurb.position < 2),
113                viewonly=True
114            )
115            blurbs = OneToMany('Blurb',
116                               collection_class=ordering_list('position'),
117                               order_by='position')
118
119        class Blurb(Entity):
120            user = ManyToOne('User')
121            position = Field(Integer)
122            blurb = Field(Unicode(255))
123
124            def __init__(self, blurb, **kwargs):
125                super(Blurb, self).__init__(blurb=blurb, **kwargs)
126
127            def __repr__(self):
128                return 'Blurb(%r, %r)' % (self.position, self.blurb)
129
130        setup_all(True)
131
132        user = User(blurbs=[Blurb(u'zero'), Blurb(u'one'), Blurb(u'two')])
133
134        session.commit()
135        session.clear()
136
137        user = User.get(1)
138        assert len(user.two_blurbs) == 2
139        assert user.two_blurbs[0].blurb == 'zero'
140        assert user.two_blurbs[1].blurb == 'one'
141
142    def test_filtered(self):
143        class User(Entity):
144            two_blurbs = OneToMany('Blurb', filter=lambda c: c.position < 2)
145            blurbs = OneToMany('Blurb',
146                               collection_class=ordering_list('position'),
147                               order_by='position')
148
149        class Blurb(Entity):
150            user = ManyToOne('User')
151            position = Field(Integer)
152            blurb = Field(Unicode(255))
153
154            def __init__(self, blurb, **kwargs):
155                super(Blurb, self).__init__(blurb=blurb, **kwargs)
156
157            def __repr__(self):
158                return 'Blurb(%r, %r)' % (self.position, self.blurb)
159
160        setup_all(True)
161
162        user = User(blurbs=[Blurb(u'zero'), Blurb(u'one'), Blurb(u'two')])
163
164        session.commit()
165        session.clear()
166
167        user = User.get(1)
168        assert len(user.two_blurbs) == 2
169        assert user.two_blurbs[0].blurb == 'zero'
170        assert user.two_blurbs[1].blurb == 'one'
171
172    def test_has_many_syntax(self):
173        class Person(Entity):
174            has_field('name', String(30))
175            has_many('pets', of_kind='Animal')
176
177        class Animal(Entity):
178            has_field('name', String(30))
179            belongs_to('owner', of_kind='Person')
180
181        setup_all(True)
182
183        santa = Person(name="Santa Claus")
184        rudolph = Animal(name="Rudolph", owner=santa)
185
186        session.commit()
187        session.clear()
188
189        santa = Person.get_by(name="Santa Claus")
190
191        assert Animal.get_by(name="Rudolph") in santa.pets
Note: See TracBrowser for help on using the browser.