Django-like test fixtures via SQLAlchemy?

684 views
Skip to first unread message

Todd Rowell

unread,
Mar 11, 2011, 2:25:16 PM3/11/11
to sqlalchemy
Hi All-

I'm a long-time Django user who has become accustomed to Django's easy
generation and loading of test fixtures (i.e., a known database state
for testing) and I'm looking for something similar for SQLAlchemy.

I've seen and been working with Kumar's fixture project (http://
pypi.python.org/pypi/fixture) but it seems largely intended to allow
loading of simpler, hand-created fixtures; support for creating
fixtures from an existing database is pretty limited and seems to
require additional coding instead of just using your existing ORM
models. It also looks like the export functionality runs a single
query at a time; not that big a limitation but not as nice as the
Django fixture generator.

I've also seen BootAlchemy, but it doesn't seem to provide for
generating fixtures.

Any ideas?

Thanks,
Todd

Michael Bayer

unread,
Mar 11, 2011, 3:30:07 PM3/11/11
to sqlal...@googlegroups.com


not knowing what a "fixture generator" means, I googled and found this:

https://github.com/alex/django-fixture-generator

Looking at that I don't see *too* much automation - at the very least I see explicit usage of models and explicit fixture data on the part of the developer. I'm not really sure what we get when we run "manage.py" though, "test_users()" and "test_groups()" already seem to be doing the work that is specific to these fixtures.

Perhaps this is one of those 20 foot cultural divide kind of things, but the problem of "consistent fixtures" is something I usually address with plain coding conventions, though the decorator trickery I see there, which appears to mark various fixture-generation methods into some kind of registry, is probably not hard to roll either, and would make a nice external project for SQLAlchemy if you were inclined.

As to how I approach that kind of thing, building off the transactional example at http://www.sqlalchemy.org/docs/orm/session.html#joining-a-session-into-an-external-transaction , these days I tend to organize fixtures, common assertion methods, into a structure like that below. Mixins define things like transactional behavior and common fixture/assertion methods:

class TransactionalTest(object):
"""Mixin which sets up/tears down a transaction"""

def setUp(self):
# connect to the database
self.connection = engine.connect()

# begin a non-ORM transaction
self.trans = connection.begin()

# bind an individual Session to the connection
self.session = Session(bind=self.connection)

def tearDown(self):
# rolls everything back.
self.session.close()
self.trans.rollback()
self.connection.close()

class UserTest(object):
"""A test that deals with User objects."""

def _user_fixture(self):
"""Example fixture method."""
self.session.add_all([User(name='ed'),User(name='wendy')])

def _assert_ed(self, user):
"""Example assertion method."""
assert user.name == 'ed', "Username is not 'ed'"

class MyTest(UserTest, TransactionalTest, TestCase):

def test_ed(self):
self._user_fixture()

ed = self.session.query(User).filter_by(name='ed').one()
self._assert_ed(ed)


>
> Any ideas?
>
> Thanks,
> Todd
>
> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To post to this group, send email to sqlal...@googlegroups.com.
> To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
>

Todd Rowell

unread,
Mar 11, 2011, 4:10:46 PM3/11/11
to sqlalchemy
Thank you for the response! However, I think I may have caused some
confusion. Let me try to clarify...


> > I'm a long-time Django user who has become accustomed to Django's easy
> > generation and loading of test fixtures (i.e., a known database state
> > for testing) and I'm looking for something similar for SQLAlchemy.
>
> > I've seen and been working with Kumar's fixture project (http://
> > pypi.python.org/pypi/fixture) but it seems largely intended to allow
> > loading of simpler, hand-created fixtures; support for creating
> > fixtures from an existing database is pretty limited and seems to
> > require additional coding instead of just using your existing ORM
> > models. It also looks like the export functionality runs a single
> > query at a time; not that big a limitation but not as nice as the
> > Django fixture generator.
>
> > I've also seen BootAlchemy, but it doesn't seem to provide for
> > generating fixtures.
>
> not knowing what a "fixture generator" means, I googled and found this:
>
> https://github.com/alex/django-fixture-generator

The confusion is more likely to be my chosen terminology. What I mean
is I want an automated way to create fixture files from an existing
database rather than writing them by hand (especially where I have a
lot of time series data that I want to use as test samples). What I
don't want is to just use a database dump, which will be brittle vis a
vis schema changes and which won't work with different DB backends.

In Django I'd just use 'manage.py dumpdata' to create my fixtures and
'manage.py loaddata' to load them ... or annotate my Django models and
tests with appropriate initial_data, but I don't need _that_ much
convenience, I'm happy to roll my own.

The django-fixture-generator code seems like way to manage fixture
creation, but I'm working at a level lower than that, still trying to
generate the data files themselves. I initially expected that I might
find
the equivalent of mysqldump but written in SQLAlchemy but haven't had
much luck there...


> As to how I approach that kind of thing, building off the transactional
> example at http://www.sqlalchemy.org/docs/orm/session.html#joining-a-session-int...,
This test setup looks pretty familiar, except for creating the test
data via Python code in the test itself. I have no problem with that
and do it on occasion, but for this application I have a lot of time
series data and want to just get it from an existing DB.

I'm totally open to the idea that I'm just not doing things the
SQLAlchemy way, or that I'm utterly spoiled by what I'm used to
getting from Django. ;-)

Thanks for the comments!
Reply all
Reply to author
Forward
0 new messages