root / elixir / trunk / tests / test_m2o.py

Revision 528, 6.9 kB (checked in by ged, 21 months ago)

- Added more tests for relationships to forward-declared entities, including

a failing one (forward reference to a non-pk column).

Line 
1"""
2test many to one relationships
3"""
4
5from elixir import *
6
7def setup():
8    metadata.bind = 'sqlite://'
9
10class TestManyToOne(object):
11    def teardown(self):
12        cleanup_all(True)
13
14    def test_simple(self):
15        class A(Entity):
16            name = Field(String(60))
17
18        class B(Entity):
19            name = Field(String(60))
20            a = ManyToOne('A')
21
22        setup_all(True)
23
24        b1 = B(name='b1', a=A(name='a1'))
25
26        session.commit()
27        session.expunge_all()
28
29        b = B.query.one()
30
31        assert b.a.name == 'a1'
32
33    def test_forward(self):
34        class A(Entity):
35            name = Field(String(60))
36
37        class B(Entity):
38            name = Field(String(60))
39            a = ManyToOne('A')
40            c = ManyToOne('C')
41
42        class C(Entity):
43            name = Field(String(60))
44
45        setup_all(True)
46
47        b1 = B(name='b1', a=A(name='a1'), c=C(name='c1'))
48
49        session.commit()
50        session.expunge_all()
51
52        b = B.query.one()
53
54        assert b.a.name == 'a1'
55        assert b.c.name == 'c1'
56
57    # this test is in test_o2m.py
58    # def test_selfref(self):
59
60    def test_with_key_pk(self):
61        class A(Entity):
62            test = Field(Integer, primary_key=True, key='testx')
63
64        class B(Entity):
65            a = ManyToOne('A')
66
67        setup_all(True)
68
69        b1 = B(a=A(testx=1))
70
71        session.commit()
72        session.expunge_all()
73
74        b = B.query.one()
75
76        assert b.a.testx == 1
77
78    def test_wh_key_in_m2o_col_kwargs(self):
79        class A(Entity):
80            name = Field(String(128), default="foo")
81
82        class B(Entity):
83            # specify a different key for the column so that
84            #  it doesn't override the property when the column
85            #  gets created.
86            a = ManyToOne('A', colname='a',
87                          column_kwargs=dict(key='a_id'))
88
89        setup_all(True)
90
91        assert 'id' in A.table.primary_key.columns
92        assert 'a_id' in B.table.columns
93
94        a = A()
95        session.commit()
96        b = B(a=a)
97        session.commit()
98        session.expunge_all()
99
100        assert B.query.first().a == A.query.first()
101
102    def test_specified_field(self):
103        class Person(Entity):
104            name = Field(String(30))
105
106        class Animal(Entity):
107            name = Field(String(30))
108            owner_id = Field(Integer, colname='owner')
109            owner = ManyToOne('Person', field=owner_id)
110
111        setup_all(True)
112
113        assert 'owner' in Animal.table.c
114        assert 'owner_id' not in Animal.table.c
115
116        homer = Person(name="Homer")
117        slh = Animal(name="Santa's Little Helper", owner=homer)
118
119        session.commit()
120        session.expunge_all()
121
122        homer = Person.get_by(name="Homer")
123        animals = Animal.query.all()
124        assert animals[0].owner is homer
125
126    def test_one_pk(self):
127        class A(Entity):
128            name = Field(String(40), primary_key=True)
129
130        class B(Entity):
131            a = ManyToOne('A', primary_key=True)
132
133        class C(Entity):
134            b = ManyToOne('B', primary_key=True)
135
136        setup_all()
137
138        assert 'name' in A.table.primary_key.columns
139        assert 'a_name' in B.table.primary_key.columns
140        assert 'b_a_name' in C.table.primary_key.columns
141
142    def test_m2o_is_only_pk(self):
143        class A(Entity):
144            pass
145
146        class B(Entity):
147            a = ManyToOne('A', primary_key=True)
148
149        setup_all()
150
151        assert 'id' in A.table.primary_key.columns
152        assert 'a_id' in B.table.primary_key.columns
153        assert 'id' not in B.table.primary_key.columns
154
155    def test_multi_pk_in_target(self):
156        class A(Entity):
157            key1 = Field(Integer, primary_key=True)
158            key2 = Field(String(40), primary_key=True)
159
160        class B(Entity):
161            num = Field(Integer, primary_key=True)
162            a = ManyToOne('A', primary_key=True)
163
164        class C(Entity):
165            num = Field(Integer, primary_key=True)
166            b = ManyToOne('B', primary_key=True)
167
168        setup_all()
169
170        assert 'key1' in A.table.primary_key.columns
171        assert 'key2' in A.table.primary_key.columns
172
173        assert 'num' in B.table.primary_key.columns
174        assert 'a_key1' in B.table.primary_key.columns
175        assert 'a_key2' in B.table.primary_key.columns
176
177        assert 'num' in C.table.primary_key.columns
178        assert 'b_num' in C.table.primary_key.columns
179        assert 'b_a_key1' in C.table.primary_key.columns
180        assert 'b_a_key2' in C.table.primary_key.columns
181
182    def test_cycle_but_use_alter(self):
183        class A(Entity):
184            c = ManyToOne('C', use_alter=True)
185
186        class B(Entity):
187            a = ManyToOne('A', primary_key=True)
188
189        class C(Entity):
190            b = ManyToOne('B', primary_key=True)
191
192        setup_all()
193
194        assert 'a_id' in B.table.primary_key.columns
195        assert 'b_a_id' in C.table.primary_key.columns
196        assert 'id' in A.table.primary_key.columns
197        assert 'c_b_a_id' in A.table.columns
198
199    def test_multi(self):
200        class A(Entity):
201            name = Field(String(32))
202
203        class B(Entity):
204            name = Field(String(15))
205
206            a_rel1 = ManyToOne('A')
207            a_rel2 = ManyToOne('A')
208
209        setup_all(True)
210
211        a1 = A(name="a1")
212        a2 = A(name="a2")
213        b1 = B(name="b1", a_rel1=a1, a_rel2=a2)
214        b2 = B(name="b2", a_rel1=a1, a_rel2=a1)
215
216        session.commit()
217        session.expunge_all()
218
219        a1 = A.get_by(name="a1")
220        a2 = A.get_by(name="a2")
221        b1 = B.get_by(name="b1")
222        b2 = B.get_by(name="b2")
223
224        assert a1 == b2.a_rel1
225        assert a2 == b1.a_rel2
226
227    def test_non_pk_target(self):
228        class A(Entity):
229            name = Field(String(60), unique=True)
230
231        class B(Entity):
232            name = Field(String(60))
233            a = ManyToOne('A', target_column=['id', 'name'])
234
235        setup_all(True)
236
237        b1 = B(name='b1', a=A(name='a1'))
238
239        session.commit()
240        session.expunge_all()
241
242        b = B.query.one()
243
244        assert b.a.name == 'a1'
245
246    # currently fails. See elixir/relationships.py:create_keys
247#    def test_non_pk_forward(self):
248#        class B(Entity):
249#            name = Field(String(60))
250#            a = ManyToOne('A', target_column=['id', 'name'])
251#
252#        class A(Entity):
253#            name = Field(String(60), unique=True)
254#
255#        setup_all(True)
256#
257#        b1 = B(name='b1', a=A(name='a1'))
258#
259#        session.commit()
260#        session.expunge_all()
261#
262#        b = B.query.one()
263#
264#        assert b.a.name == 'a1'
265
266    def test_belongs_to_syntax(self):
267        class Person(Entity):
268            has_field('name', String(30))
269
270        class Animal(Entity):
271            has_field('name', String(30))
272            belongs_to('owner', of_kind='Person')
273
274        setup_all(True)
275
276        santa = Person(name="Santa Claus")
277        rudolph = Animal(name="Rudolph", owner=santa)
278
279        session.commit()
280        session.expunge_all()
281
282        assert "Claus" in Animal.get_by(name="Rudolph").owner.name
Note: See TracBrowser for help on using the browser.