9
9
from sqlalchemy import *
10
10
from sqlalchemy.orm import *
11
11
from sqlalchemy.test import *
15
13
dbapi_session = engines.ReplayableSession()
18
17
class ZooMarkTest(TestBase):
19
19
"""Runs the ZooMark and squawks if method counts vary from the norm.
21
Each test has an associated `call_range`, the total number of accepted
22
function calls made during the test. The count can vary between Python
21
Each test has an associated `call_range`, the total number of
22
accepted function calls made during the test. The count can vary
23
between Python 2.4 and 2.5.
25
25
Unlike a unit test, this is a ordered collection of steps. Running
26
26
components individually will fail.
30
30
__only_on__ = 'postgresql+psycopg2'
31
__skip_if__ = ((lambda: sys.version_info < (2, 5)), ) # TODO: get 2.4 support
31
__skip_if__ = lambda : sys.version_info < (2, 5), # TODO: get 2.4
33
34
def test_baseline_0_setup(self):
34
35
global metadata, session
36
36
creator = testing.db.pool._creator
37
recorder = lambda: dbapi_session.recorder(creator())
38
engine = engines.testing_engine(options={'creator':recorder})
37
recorder = lambda : dbapi_session.recorder(creator())
38
engine = engines.testing_engine(options={'creator': recorder})
39
39
metadata = MetaData(engine)
40
40
session = sessionmaker()()
43
43
def test_baseline_1_create_tables(self):
44
zoo = Table('Zoo', metadata,
45
Column('ID', Integer, Sequence('zoo_id_seq'),
46
primary_key=True, index=True),
47
Column('Name', Unicode(255)),
48
Column('Founded', Date),
49
Column('Opens', Time),
50
Column('LastEscape', DateTime),
51
Column('Admission', Float),
54
animal = Table('Animal', metadata,
55
Column('ID', Integer, Sequence('animal_id_seq'),
57
Column('ZooID', Integer, ForeignKey('Zoo.ID'),
59
Column('Name', Unicode(100)),
60
Column('Species', Unicode(100)),
61
Column('Legs', Integer, default=4),
62
Column('LastEscape', DateTime),
63
Column('Lifespan', Float(4)),
64
Column('MotherID', Integer, ForeignKey('Animal.ID')),
65
Column('PreferredFoodID', Integer),
66
Column('AlternateFoodID', Integer),
47
Column('ID', Integer, Sequence('zoo_id_seq'),
48
primary_key=True, index=True),
49
Column('Name', Unicode(255)),
50
Column('Founded', Date),
51
Column('Opens', Time),
52
Column('LastEscape', DateTime),
53
Column('Admission', Float),
58
Column('ID', Integer, Sequence('animal_id_seq'),
60
Column('ZooID', Integer, ForeignKey('Zoo.ID'), index=True),
61
Column('Name', Unicode(100)),
62
Column('Species', Unicode(100)),
63
Column('Legs', Integer, default=4),
64
Column('LastEscape', DateTime),
65
Column('Lifespan', Float(4)),
66
Column('MotherID', Integer, ForeignKey('Animal.ID')),
67
Column('PreferredFoodID', Integer),
68
Column('AlternateFoodID', Integer),
68
70
metadata.create_all()
72
76
def __init__(self, **kwargs):
73
77
for k, v in kwargs.iteritems():
74
78
setattr(self, k, v)
75
81
class Animal(object):
76
83
def __init__(self, **kwargs):
77
84
for k, v in kwargs.iteritems():
78
85
setattr(self, k, v)
80
89
mapper(Animal, animal)
82
91
def test_baseline_1a_populate(self):
83
wap = Zoo(Name=u'Wild Animal Park',
84
Founded=datetime.date(2000, 1, 1),
85
# 59 can give rounding errors with divmod, which
86
# AdapterFromADO needs to correct.
87
Opens=datetime.time(8, 15, 59),
88
LastEscape=datetime.datetime(2004, 7, 29, 5, 6, 7),
92
wap = Zoo(Name=u'Wild Animal Park', Founded=datetime.date(2000,
93
1, 1), Opens=datetime.time(8, 15, 59),
94
LastEscape=datetime.datetime( 2004, 7, 29, 5, 6, 7, ),
92
sdz = Zoo(Name =u'San Diego Zoo',
93
# This early date should play havoc with a number
95
Founded = datetime.date(1835, 9, 13),
96
Opens = datetime.time(9, 0, 0),
97
sdz = Zoo(Name=u'San Diego Zoo', Founded=datetime.date(1835, 9,
98
13), Opens=datetime.time(9, 0, 0), Admission=0)
102
Name = u'Montr\xe9al Biod\xf4me',
103
Founded = datetime.date(1992, 6, 19),
104
Opens = datetime.time(9, 0, 0),
100
bio = Zoo(Name=u'Montr\xe9al Biod\xf4me',
101
Founded=datetime.date(1992, 6, 19),
102
Opens=datetime.time(9, 0, 0), Admission=11.75)
110
Name =u'Sea_World', Admission = 60)
104
seaworld = Zoo(Name=u'Sea_World', Admission=60)
111
105
session.add(seaworld)
113
107
# Let's add a crazy futuristic Zoo to test large date values.
114
lp = Zoo(Name =u'Luna Park',
115
Founded = datetime.date(2072, 7, 17),
116
Opens = datetime.time(0, 0, 0),
109
lp = Zoo(Name=u'Luna Park', Founded=datetime.date(2072, 7, 17),
110
Opens=datetime.time(0, 0, 0), Admission=134.95)
123
leopard = Animal(Species=u'Leopard', Lifespan=73.5,)
116
leopard = Animal(Species=u'Leopard', Lifespan=73.5)
124
117
session.add(leopard)
125
118
leopard.ZooID = wap.ID
126
leopard.LastEscape = datetime.datetime(2004, 12, 21, 8, 15, 0, 999907)
119
leopard.LastEscape = \
120
datetime.datetime(2004, 12, 21, 8, 15, 0, 999907, )
128
121
session.add(Animal(Species=u'Lion', ZooID=wap.ID))
129
122
session.add(Animal(Species=u'Slug', Legs=1, Lifespan=.75))
130
123
session.add(Animal(Species=u'Tiger', ZooID=sdz.ID))
132
125
# Override Legs.default with itself just to make sure it works.
133
127
session.add(Animal(Species=u'Bear', Legs=4))
134
128
session.add(Animal(Species=u'Ostrich', Legs=2, Lifespan=103.2))
135
129
session.add(Animal(Species=u'Centipede', Legs=100))
137
session.add(Animal(Species=u'Emperor Penguin', Legs=2, ZooID=seaworld.ID))
138
session.add(Animal(Species=u'Adelie Penguin', Legs=2, ZooID=seaworld.ID))
140
session.add(Animal(Species=u'Millipede', Legs=1000000, ZooID=sdz.ID))
130
session.add(Animal(Species=u'Emperor Penguin', Legs=2,
132
session.add(Animal(Species=u'Adelie Penguin', Legs=2,
134
session.add(Animal(Species=u'Millipede', Legs=1000000,
142
137
# Add a mother and child to test relationships
143
139
bai_yun = Animal(Species=u'Ape', Nameu=u'Bai Yun', Legs=2)
144
140
session.add(bai_yun)
145
141
session.add(Animal(Species=u'Ape', Name=u'Hua Mei', Legs=2,
146
MotherID=bai_yun.ID))
142
MotherID=bai_yun.ID))
150
146
def test_baseline_2_insert(self):
151
147
for x in xrange(ITERATIONS):
152
session.add(Animal(Species=u'Tick', Name=u'Tick %d' % x, Legs=8))
148
session.add(Animal(Species=u'Tick', Name=u'Tick %d' % x,
155
152
def test_baseline_3_properties(self):
156
153
for x in xrange(ITERATIONS):
158
WAP = list(session.query(Zoo).filter(Zoo.Name==u'Wild Animal Park'))
159
SDZ = list(session.query(Zoo).filter(Zoo.Founded==datetime.date(1835, 9, 13)))
160
Biodome = list(session.query(Zoo).filter(Zoo.Name==u'Montr\xe9al Biod\xf4me'))
161
seaworld = list(session.query(Zoo).filter(Zoo.Admission == float(60)))
157
WAP = list(session.query(Zoo).filter(Zoo.Name
158
== u'Wild Animal Park'))
159
SDZ = list(session.query(Zoo).filter(Zoo.Founded
160
== datetime.date(1835, 9, 13)))
161
Biodome = list(session.query(Zoo).filter(Zoo.Name
162
== u'Montr\xe9al Biod\xf4me'))
163
seaworld = list(session.query(Zoo).filter(Zoo.Admission
164
leopard = list(session.query(Animal).filter(Animal.Species == u'Leopard'))
165
ostrich = list(session.query(Animal).filter(Animal.Species==u'Ostrich'))
166
millipede = list(session.query(Animal).filter(Animal.Legs==1000000))
167
ticks = list(session.query(Animal).filter(Animal.Species==u'Tick'))
168
leopard = list(session.query(Animal).filter(Animal.Species
170
ostrich = list(session.query(Animal).filter(Animal.Species
172
millipede = list(session.query(Animal).filter(Animal.Legs
174
ticks = list(session.query(Animal).filter(Animal.Species
169
177
def test_baseline_4_expressions(self):
170
178
for x in xrange(ITERATIONS):
171
179
assert len(list(session.query(Zoo))) == 5
172
180
assert len(list(session.query(Animal))) == ITERATIONS + 12
173
assert len(list(session.query(Animal).filter(Animal.Legs==4))) == 4
174
assert len(list(session.query(Animal).filter(Animal.Legs == 2))) == 5
175
assert len(list(session.query(Animal).filter(and_(Animal.Legs >= 2, Animal.Legs < 20)))) == ITERATIONS + 9
176
assert len(list(session.query(Animal).filter(Animal.Legs > 10))) == 2
177
assert len(list(session.query(Animal).filter(Animal.Lifespan > 70))) == 2
178
assert len(list(session.query(Animal).filter(Animal.Species.like(u'L%')))) == 2
179
assert len(list(session.query(Animal).filter(Animal.Species.like(u'%pede')))) == 2
181
assert len(list(session.query(Animal).filter(Animal.LastEscape != None))) == 1
182
assert len(list(session.query(Animal).filter(Animal.LastEscape == None))) == ITERATIONS + 11
181
assert len(list(session.query(Animal).filter(Animal.Legs
183
assert len(list(session.query(Animal).filter(Animal.Legs
185
assert len(list(session.query(Animal).filter(and_(Animal.Legs
186
>= 2, Animal.Legs < 20)))) == ITERATIONS + 9
187
assert len(list(session.query(Animal).filter(Animal.Legs
189
assert len(list(session.query(Animal).filter(Animal.Lifespan
191
assert len(list(session.query(Animal).
192
filter(Animal.Species.like(u'L%')))) == 2
193
assert len(list(session.query(Animal).
194
filter(Animal.Species.like(u'%pede')))) == 2
195
assert len(list(session.query(Animal).filter(Animal.LastEscape
197
assert len(list(session.query(Animal).filter(Animal.LastEscape
198
== None))) == ITERATIONS + 11
184
200
# In operator (containedby)
185
assert len(list(session.query(Animal).filter(Animal.Species.like(u'%pede%')))) == 2
186
202
assert len(list(session.query(Animal).filter(
187
Animal.Species.in_((u'Lion', u'Tiger', u'Bear'))))) == 3
203
Animal.Species.like(u'%pede%')))) == 2
204
assert len(list(session.query(Animal).
205
filter(Animal.Species.in_((u'Lion'
206
, u'Tiger', u'Bear'))))) == 3
189
208
# Try In with cell references
190
class thing(object): pass
191
212
pet, pet2 = thing(), thing()
192
213
pet.Name, pet2.Name = u'Slug', u'Ostrich'
193
assert len(list(session.query(Animal).filter(Animal.Species.in_((pet.Name, pet2.Name))))) == 2
214
assert len(list(session.query(Animal).
215
filter(Animal.Species.in_((pet.Name,
195
218
# logic and other functions
197
assert len(list(session.query(Animal).filter(func.length(Animal.Species) == len(name)))) == ITERATIONS + 3
199
assert len(list(session.query(Animal).filter(Animal.Species.like(u'%i%')))) == ITERATIONS + 7
221
assert len(list(session.query(Animal).
222
filter(func.length(Animal.Species)
223
== len(name)))) == ITERATIONS + 3
224
assert len(list(session.query(Animal).
225
filter(Animal.Species.like(u'%i%'
226
)))) == ITERATIONS + 7
201
228
# Test now(), today(), year(), month(), day()
202
assert len(list(session.query(Zoo).filter(and_(Zoo.Founded != None, Zoo.Founded < func.now())))) == 3
203
assert len(list(session.query(Animal).filter(Animal.LastEscape == func.now()))) == 0
204
assert len(list(session.query(Animal).filter(func.date_part('year', Animal.LastEscape) == 2004))) == 1
205
assert len(list(session.query(Animal).filter(func.date_part('month', Animal.LastEscape) == 12))) == 1
206
assert len(list(session.query(Animal).filter(func.date_part('day', Animal.LastEscape) == 21))) == 1
230
assert len(list(session.query(Zoo).filter(and_(Zoo.Founded
231
!= None, Zoo.Founded < func.now())))) == 3
232
assert len(list(session.query(Animal).filter(Animal.LastEscape
233
== func.now()))) == 0
234
assert len(list(session.query(Animal).filter(func.date_part('year'
235
, Animal.LastEscape) == 2004))) == 1
236
assert len(list(session.query(Animal).
237
filter(func.date_part('month'
238
, Animal.LastEscape) == 12))) == 1
239
assert len(list(session.query(Animal).filter(func.date_part('day'
240
, Animal.LastEscape) == 21))) == 1
208
242
def test_baseline_5_aggregates(self):
209
243
Animal = metadata.tables['Animal']
210
244
Zoo = metadata.tables['Zoo']
212
246
# TODO: convert to ORM
213
248
for x in xrange(ITERATIONS):
215
252
view = select([Animal.c.Legs]).execute().fetchall()
216
253
legs = [x[0] for x in view]
219
expected = {'Leopard': 73.5,
226
'Emperor Penguin': None,
227
'Adelie Penguin': None,
232
for species, lifespan in select([Animal.c.Species, Animal.c.Lifespan]
233
).execute().fetchall():
263
'Emperor Penguin': None,
264
'Adelie Penguin': None,
269
for species, lifespan in select([Animal.c.Species,
270
Animal.c.Lifespan]).execute().fetchall():
234
271
assert lifespan == expected[species]
236
272
expected = [u'Montr\xe9al Biod\xf4me', 'Wild Animal Park']
237
e = select([Zoo.c.Name],
238
and_(Zoo.c.Founded != None,
239
Zoo.c.Founded <= func.current_timestamp(),
240
Zoo.c.Founded >= datetime.date(1990, 1, 1)))
273
e = select([Zoo.c.Name], and_(Zoo.c.Founded != None,
274
Zoo.c.Founded <= func.current_timestamp(),
275
Zoo.c.Founded >= datetime.date(1990, 1, 1)))
241
276
values = [val[0] for val in e.execute().fetchall()]
242
277
assert set(values) == set(expected)
245
legs = [x[0] for x in
246
select([Animal.c.Legs], distinct=True).execute().fetchall()]
281
legs = [x[0] for x in select([Animal.c.Legs],
282
distinct=True).execute().fetchall()]
249
285
def test_baseline_6_editing(self):
250
286
for x in xrange(ITERATIONS):
252
SDZ = session.query(Zoo).filter(Zoo.Name==u'San Diego Zoo').one()
290
SDZ = session.query(Zoo).filter(Zoo.Name == u'San Diego Zoo'
253
292
SDZ.Name = u'The San Diego Zoo'
254
293
SDZ.Founded = datetime.date(1900, 1, 1)
255
294
SDZ.Opens = datetime.time(7, 30, 0)
256
295
SDZ.Admission = 35.00
259
SDZ = session.query(Zoo).filter(Zoo.Name==u'The San Diego Zoo').one()
299
SDZ = session.query(Zoo).filter(Zoo.Name
300
== u'The San Diego Zoo').one()
260
301
assert SDZ.Founded == datetime.date(1900, 1, 1), SDZ.Founded
263
305
SDZ.Name = u'San Diego Zoo'
264
306
SDZ.Founded = datetime.date(1835, 9, 13)
265
307
SDZ.Opens = datetime.time(9, 0, 0)
266
308
SDZ.Admission = 0
269
SDZ = session.query(Zoo).filter(Zoo.Name==u'San Diego Zoo').one()
270
assert SDZ.Founded == datetime.date(1835, 9, 13), SDZ.Founded
312
SDZ = session.query(Zoo).filter(Zoo.Name == u'San Diego Zoo'
314
assert SDZ.Founded == datetime.date(1835, 9, 13), \
272
317
def test_baseline_7_drop(self):
273
318
session.rollback()
274
319
metadata.drop_all()
276
# Now, run all of these tests again with the DB-API driver factored out:
277
# the ReplayableSession playback stands in for the database.
321
# Now, run all of these tests again with the DB-API driver factored
322
# out: the ReplayableSession playback stands in for the database.
279
324
# How awkward is this in a unittest framework? Very.
281
326
def test_profile_0(self):
282
327
global metadata, session
284
player = lambda: dbapi_session.player()
328
player = lambda : dbapi_session.player()
285
329
engine = create_engine('postgresql:///', creator=player)
286
330
metadata = MetaData(engine)
287
331
session = sessionmaker()()
290
334
@profiling.function_call_count(4898)
291
335
def test_profile_1_create_tables(self):
292
336
self.test_baseline_1_create_tables()