root / elixir / trunk / tests / test_options.py

Revision 505, 7.5 kB (checked in by ged, 3 years ago)

- using_options_defaults and using_table_options statements can be used several

times within the same class (closes #70).

Line 
1"""
2test options
3"""
4
5from sqlalchemy import UniqueConstraint, create_engine, Column
6from sqlalchemy.orm import scoped_session, sessionmaker
7from sqlalchemy.exceptions import SQLError, ConcurrentModificationError
8from elixir import *
9
10class TestOptions(object):
11    def setup(self):
12        metadata.bind = 'sqlite://'
13
14    def teardown(self):
15        cleanup_all(True)
16
17    # this test is a rip-off SQLAlchemy's activemapper's update test
18    def test_version_id_col(self):
19        class Person(Entity):
20            name = Field(String(30))
21
22            using_options(version_id_col=True)
23
24        setup_all(True)
25
26        p1 = Person(name='Daniel')
27        session.commit()
28        session.expunge_all()
29
30        person = Person.query.first()
31        person.name = 'Gaetan'
32        session.commit()
33        assert person.row_version == 2
34        session.expunge_all()
35
36        person = Person.query.first()
37        person.name = 'Jonathan'
38        session.commit()
39        assert person.row_version == 3
40        session.expunge_all()
41
42        # check that a concurrent modification raises exception
43        p1 = Person.query.first()
44        s2 = sessionmaker()()
45        p2 = s2.query(Person).first()
46        p1.name = "Daniel"
47        p2.name = "Gaetan"
48        s2.commit()
49        try:
50            session.commit()
51            assert False
52        except ConcurrentModificationError:
53            pass
54        s2.close()
55
56    def test_allowcoloverride_false(self):
57        class MyEntity(Entity):
58            name = Field(String(30))
59
60        setup_all(True)
61
62        try:
63            MyEntity._descriptor.add_column(Column('name', String(30)))
64            assert False
65        except Exception:
66            pass
67
68    def test_allowcoloverride_true(self):
69        class MyEntity(Entity):
70            name = Field(String(30))
71            using_options(allowcoloverride=True)
72
73        setup_all()
74
75        # Note that this test is bogus as you cannot just change a column this
76        # way since the mapper is already constructed at this point and will
77        # use the old column!!! This test is only meant as a way to check no
78        # exception is raised.
79        #TODO: provide a proper test (using autoloaded tables)
80        MyEntity._descriptor.add_column(Column('name', String(30),
81                                               default='test'))
82
83    def test_tablename_func(self):
84        import re
85
86        def camel_to_underscore(entity):
87            return re.sub(r'(.+?)([A-Z])+?', r'\1_\2', entity.__name__).lower()
88
89        options_defaults['tablename'] = camel_to_underscore
90
91        class MyEntity(Entity):
92            name = Field(String(30))
93
94        class MySuperTestEntity(Entity):
95            name = Field(String(30))
96
97        setup_all(True)
98
99        assert MyEntity.table.name == 'my_entity'
100        assert MySuperTestEntity.table.name == 'my_super_test_entity'
101
102        options_defaults['tablename'] = None
103
104
105class TestSessionOptions(object):
106    def setup(self):
107        metadata.bind = None
108
109    def teardown(self):
110        cleanup_all()
111
112    def test_manual_session(self):
113        engine = create_engine('sqlite://')
114
115        class Person(Entity):
116            using_options(session=None)
117            name = Field(String(30))
118
119        setup_all()
120        create_all(engine)
121
122        Session = sessionmaker(bind=engine)
123        session = Session()
124
125        homer = Person(name="Homer")
126        bart = Person(name="Bart")
127
128        session.add(homer)
129        session.add(bart)
130        session.commit()
131
132        bart.delete()
133        session.commit()
134
135        assert session.query(Person).filter_by(name='Homer').one() is \
136               homer
137        assert session.query(Person).count() == 1
138
139    def test_scoped_session(self):
140        engine = create_engine('sqlite://')
141        Session = scoped_session(sessionmaker(bind=engine))
142
143        class Person(Entity):
144            using_options(session=Session)
145            name = Field(String(30))
146
147        setup_all()
148        create_all(engine)
149
150        homer = Person(name="Homer")
151        bart = Person(name="Bart")
152        Session.commit()
153
154        assert Person.query.session is Session()
155        assert Person.query.filter_by(name='Homer').one() is homer
156
157    def test_scoped_session_no_save_on_init(self):
158        metadata.bind = 'sqlite://'
159
160        class Person(Entity):
161            using_mapper_options(save_on_init=False)
162            name = Field(String(30))
163
164        setup_all(True)
165
166        homer = Person(name="Homer")
167        bart = Person(name="Bart")
168        assert homer not in session
169        assert bart not in session
170        session.add(homer)
171        session.add(bart)
172        session.commit()
173
174        assert Person.query.filter_by(name='Homer').one() is homer
175
176    def test_global_scoped_session(self):
177        global __session__
178
179        engine = create_engine('sqlite://')
180        session = scoped_session(sessionmaker(bind=engine))
181        __session__ = session
182
183        class Person(Entity):
184            name = Field(String(30))
185
186        setup_all()
187        create_all(engine)
188
189        homer = Person(name="Homer")
190        bart = Person(name="Bart")
191        session.commit()
192
193        assert Person.query.session is session()
194        assert Person.query.filter_by(name='Homer').one() is homer
195
196        del __session__
197
198
199class TestTableOptions(object):
200    def setup(self):
201        metadata.bind = 'sqlite://'
202
203    def teardown(self):
204        cleanup_all(True)
205
206    def test_unique_constraint(self):
207        class Person(Entity):
208            firstname = Field(String(30))
209            surname = Field(String(30))
210
211            using_table_options(UniqueConstraint('firstname', 'surname'))
212
213        setup_all(True)
214
215        homer = Person(firstname="Homer", surname='Simpson')
216        bart = Person(firstname="Bart", surname='Simpson')
217
218        session.commit()
219
220        homer2 = Person(firstname="Homer", surname='Simpson')
221
222        try:
223            session.commit()
224            assert False
225        except SQLError:
226            pass
227
228    def test_several_statements(self):
229        class A(Entity):
230            name1 = Field(String(30))
231            name2 = Field(String(30))
232            name3 = Field(String(30))
233            using_table_options(UniqueConstraint('name1', 'name2'))
234            using_table_options(UniqueConstraint('name2', 'name3'))
235
236        setup_all(True)
237
238        a000 = A(name1='0', name2='0', name3='0')
239        a010 = A(name1='0', name2='1', name3='0')
240        session.commit()
241
242        a001 = A(name1='0', name2='0', name3='1')
243        try:
244            session.commit()
245            assert False
246        except SQLError:
247            session.close()
248
249        a100 = A(name1='1', name2='0', name3='0')
250        try:
251            session.commit()
252            assert False
253        except SQLError:
254            session.close()
255
256    def test_unique_constraint_many_to_one(self):
257        class Author(Entity):
258            name = Field(String(50))
259
260        class Book(Entity):
261            title = Field(String(200), required=True)
262            author = ManyToOne("Author")
263
264            using_table_options(UniqueConstraint("title", "author_id"))
265
266        setup_all(True)
267
268        tolkien = Author(name="J. R. R. Tolkien")
269        lotr = Book(title="The Lord of the Rings", author=tolkien)
270        hobbit = Book(title="The Hobbit", author=tolkien)
271
272        session.commit()
273
274        tolkien2 = Author(name="Tolkien")
275        hobbit2 = Book(title="The Hobbit", author=tolkien2)
276
277        session.commit()
278
279        hobbit3 = Book(title="The Hobbit", author=tolkien)
280
281        raised = False
282        try:
283            session.commit()
284        except SQLError:
285            raised = True
286
287        assert raised
Note: See TracBrowser for help on using the browser.