Fixture migrations using South?

20 views
Skip to first unread message

Jeremy Dunck

unread,
Nov 30, 2011, 12:26:26 PM11/30/11
to django...@googlegroups.com, south...@googlegroups.com
I have some test fixtures with scenarios under test. Later, I need to
migrate (with South) the DB schema around, which of cours necessitates
changing domain and test code.

A common problem I run into, though, is that I also need to migrate
the data in my fixtures. It is possible to create a new DB, sync it
to a given migration point, load the fixture, run the remaining
migrations, and dump a new fixture, then drop the extra db. But it
seems like a very awkward dance given how often I have the problem.

Is there already a solution to this? It seems to me that South could
manage some book keeping to maintain what fixtures are at which
migration level, and a new south command could manage the migration of
fixtures.

./manage migrate --fixtures [all other options staying the same]

I imagine this would read/write some bookmark files to each affected
app's ./fixtures/ directory. If the bookmark file didn't exist, the
0001 schema would be assumed. Otherwise it'd be something along the
lines of:
fixture_file.name.south, and contents would roughly mirror
south_migrationhistory, perhaps in JSON format.

Thoughts?

Evgeny Fadeev

unread,
Nov 30, 2011, 1:06:56 PM11/30/11
to south...@googlegroups.com
Hi, we've just implemented a script populating the application with test data
and creating the test fixture.

Take a look here:

I think there is an app also that allows you to dump data in the form of a script,
which might also be helpful.

It might be a hassle to create a test data builder by hand, but in the future you can maintain it, 
and it should be quite easy to extend.

Cheers,
Evgeny.




--
You received this message because you are subscribed to the Google Groups "South Users" group.
To post to this group, send email to south...@googlegroups.com.
To unsubscribe from this group, send email to south-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/south-users?hl=en.




--
Askbot
Santiago, Chile
skype: evgeny-fadeev

Jeremy Dunck

unread,
Nov 30, 2011, 3:08:49 PM11/30/11
to south...@googlegroups.com
On Wed, Nov 30, 2011 at 10:06 AM, Evgeny Fadeev <evgeny...@gmail.com> wrote:
> Hi, we've just implemented a script populating the application with test
> data
> and creating the test fixture.
>
> Take a look here:
> https://github.com/ASKBOT/askbot-devel/blob/master/askbot/management/commands/askbot_create_test_fixture.py
> https://github.com/ASKBOT/askbot-devel/blob/master/askbot/management/commands/askbot_add_test_content.py

Hmm, so with that approach you're treating the fixture as a sort of
compilation artifact. I hadn't considered that before, but I suppose
it does sidestep the problem of fixture migration.

I just assumed my approach was "the way" - to prepare a dataset for
testing once, then add to it as necessary, but not scripted
generation.

Which is common practice here?

> I think there is an app also that allows you to dump data in the form of a
> script,
> which might also be helpful.

OK, does anyone know the name of that app?

> It might be a hassle to create a test data builder by hand, but in the
> future you can maintain it,
> and it should be quite easy to extend.

Some part of it will be an unavoidable hassle, but yes, I'm seeking to
make it suck less. :-)

Evgeny Fadeev

unread,
Nov 30, 2011, 3:17:48 PM11/30/11
to south...@googlegroups.com
...


> I think there is an app also that allows you to dump data in the form of a
> script,
> which might also be helpful.

OK, does anyone know the name of that app?

Evgeny Fadeev

unread,
Nov 30, 2011, 3:22:39 PM11/30/11
to south...@googlegroups.com
But the potential problems with the dumpscript are:

* as database changes you need to re-create the script dump
* if you are using postsave and presave and modify data via signal handlers,
  rerunning the script dump may not be able to reproduce the state of the database - this I'm just guessing - 
  never tested.

What we have done - using an api - not Django ORM populate the data.
So the hassle here is to first create an api for your data model which will not be changing as often
as your data models, and then using the api write the test data builder.

Carl Meyer

unread,
Nov 30, 2011, 3:46:35 PM11/30/11
to south...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/30/2011 01:08 PM, Jeremy Dunck wrote:
> Hmm, so with that approach you're treating the fixture as a sort of
> compilation artifact. I hadn't considered that before, but I suppose
> it does sidestep the problem of fixture migration.
>
> I just assumed my approach was "the way" - to prepare a dataset for
> testing once, then add to it as necessary, but not scripted
> generation.
>
> Which is common practice here?

I can't speak for common practice, but personally I find test data
fixtures to be way more headache than they are worth. Scripting their
generation helps a bit, but at that point why not take it one step
further and just write test data building utilities so your tests can
create exactly the test data they need in a line or two? I've stopped
using fixtures entirely in favor of test data builders, and AFAICS it's
a win in every way. Not only sidesteps migration issues, but all sorts
of hassles around modifying fixtures in general, and reduces test
interdependencies ("I thought these tests all needed the same data, but
now I need this extra thing in the fixture for this test, and that's
going to change the results of all these tests...").

>> I think there is an app also that allows you to dump data in the form of a
>> script,
>> which might also be helpful.
>
> OK, does anyone know the name of that app?

There may be another one, but django-extensions has a dump_script
management command. I used to use it, but it has most of the same issues
as fixtures.

>> It might be a hassle to create a test data builder by hand, but in the
>> future you can maintain it,
>> and it should be quite easy to extend.
>
> Some part of it will be an unavoidable hassle, but yes, I'm seeking to
> make it suck less. :-)

I find creating test data builders to be less hassle than the other
options. Here's what mine tend to look like in their simplest form:

def create_person(**kwargs):
defaults = {"name": "Jane Doe", "age": 29}
defaults.update(kwargs)
return Person.objects.create(**defaults)

Of course, in real situations there tend to be additional complexities
(creating dependent objects, etc), but still easy; nothing like fixture
hassles. You can also write higher-level builders to create a set of
inter-related data that multiple tests might use, though I don't find I
need those very often: it's pretty easy, and more explicit, to use some
model-level builders in a loop or whatever right in the test.

Carl
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk7WlisACgkQ8W4rlRKtE2e9DgCdGUJjgYzYvChVRcxSdjaTBubG
pRQAn1iHVoCLQ9c+JCMr16++eXHP9K1R
=X+LD
-----END PGP SIGNATURE-----

Jeremy Dunck

unread,
Nov 30, 2011, 4:57:27 PM11/30/11
to south...@googlegroups.com
On Wed, Nov 30, 2011 at 12:46 PM, Carl Meyer <ca...@oddbird.net> wrote:
...

> I can't speak for common practice, but personally I find test data
> fixtures to be way more headache than they are worth. Scripting their
> generation helps a bit, but at that point why not take it one step
> further and just write test data building utilities so your tests can
> create exactly the test data they need in a line or two?

To be honest, I/we do this with a good section of our harness data. I
suppose most of what I have in fixtures is more like reference data,
but the schema does still change at times.

In fact, we have a create_user, etc. :-)

> I've stopped
> using fixtures entirely in favor of test data builders, and AFAICS it's
> a win in every way.

Perhaps I should ask on django-dev whether anybody who has tried both
strongly prefers fixtures and why. I hear what you're saying and
generally don't disagree, but it seems odd to advertise a feature
which doesn't really solve the goal problem well. Perhaps we should
do a guide on different approaches to test data.

I do think some of the suck around fixtures is that tooling around it
hasn't been built up.

> Not only sidesteps migration issues, but all sorts
> of hassles around modifying fixtures in general, and reduces test
> interdependencies ("I thought these tests all needed the same data, but
> now I need this extra thing in the fixture for this test, and that's
> going to change the results of all these tests...").

I see that action-at-a distance problem too, but I do think that one
thing fixtures going for them is that you can prepare fixtures closer
to real-world datasets than you're likely to do as a piece of unit
testing.

Anyway, now that we're talking more about the general problem than the
idea of a feature for south, I fear we may be off-topic. But I'm not
sure of a more appropriate forum. What says the list? Should we take
it off-list?

>>> I think there is an app also that allows you to dump data in the form of a
>>> script,
>>> which might also be helpful.
>>
>> OK, does anyone know the name of that app?
>
> There may be another one, but django-extensions has a dump_script
> management command. I used to use it, but it has most of the same issues
> as fixtures.
>
>>> It might be a hassle to create a test data builder by hand, but in the
>>> future you can maintain it,
>>> and it should be quite easy to extend.
>>
>> Some part of it will be an unavoidable hassle, but yes, I'm seeking to
>> make it suck less. :-)
>
> I find creating test data builders to be less hassle than the other
> options. Here's what mine tend to look like in their simplest form:
>
> def create_person(**kwargs):
>    defaults = {"name": "Jane Doe", "age": 29}
>    defaults.update(kwargs)
>    return Person.objects.create(**defaults)
>
> Of course, in real situations there tend to be additional complexities
> (creating dependent objects, etc), but still easy; nothing like fixture
> hassles. You can also write higher-level builders to create a set of
> inter-related data that multiple tests might use, though I don't find I
> need those very often: it's pretty easy, and more explicit, to use some
> model-level builders in a loop or whatever right in the test.

Again, mostly I agree, but it feels to me like a django-admin
testshell (to go with testserver) and a south migrate --fixture would
help a lot in making fixtures more practical.

On that point, I'll go to dj-dev to propose a guide and testshell to
see what people think.

Reply all
Reply to author
Forward
0 new messages