Newer version available (0.1.1)
Close
New issue commented
commented
commented
Mar 29, 2009 - dumpdata without MemoryErrors, with progress notification. Raise raise CommandError('Unable to serialize database:%s'% e).
Last released:
dumpdata generates python source code files as the fixtures
Project description
# About
Django fixtures can lead to maintenance problems. You often forget to update them when you refactor your models. Other times, you have to try to fix them by hand and find yourself in a morass of primary keys. In general, they are fragile.
Many experts suggest that you forgo fixtures and write your own object factories. Great idea! Here is a tool to help you get started. Using the regular Django `dumpdata` command, pyfixtures will generate a python file that contains all the code necessary to re-constitute that data in an empty database. You can take that code and refactor it into something you maintain going forward, or you can re-generate it from a target database when needed.
# Install
### Add to INSTALLED_APPS
In your `settings.py`, add `pyfixtures` to the INSTALLED_APPS setting:
```python
INSTALLED_APPS = (
...
'pyfixtures',
)
```
### Set SERIALIZATION_MODULES
```bash
SERIALIZATION_MODULES = {'py': 'pyfixtures.serializer'}
```
# Usage
Use the regular Django dumpdata command, but with the format set to pyfixtures.
```bash
./manage.py dumpdata --exclude contenttypes --format=py > fixtures/initial_data.py
```
You can also use the `loaddata` command on that file, as you would expect.
```bash
./manage.py loaddata fixtures/initial_data.py
```
# Settings
```bash
PYFIXTURES_CIRCULAR_DEP_BREAKERS = ('Organization', 'Group', 'WorkflowHistory')
```
If you run into problems serializing your models due to circular dependencies, pyfixtures will prompt you to 'break the tie' by designating one or more of your models to use primary keys directly in the constructors.
You'll know if you need to use this setting if you see something like the following when you run dumpdata:
```bash
InfractionType depends on ['WorkflowItem']
WorkflowItem depends on ['WorkflowHistory']
WorkflowHistory depends on ['WorkflowItem']
Error: Unable to serialize database: Could not sort objects in dependency order, is there a circular dependency?
```
# Writing Your own Fixtures
The fixtures are mostly what you would expect. You import models that you need, and declare your objects. The fixtures that we generate don't use loops, but you can if you want to.
Because Django's `loaddata` command expects to save the models itself, we don't call `save()` on the models directly in the fixture. Instead, anything you define in the scope of the fixture file that inherits from Django's Model class will be saved when `loaddata` runs.
This is slightly at odds with how many to many relationships work in Django. Normally, you would structure your code like this:
```python
from django.db import models
class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
p1 = Publication(title='The Python Journal')
p1.save()
a1 = Article(headline='Django lets you build Web apps easily')
a1.publications.add(p1)
```
Because we need to defer the saving of your models, we use the following mechanism to declare many to many relationships. You should follow this convention if you write your own fixtures.
```python
p1 = Publication(title='The Python Journal')
a1 = Article(headline='Django lets you build Web apps easily')
a1.m2m_data = {'publications': [p1]}
```
Django fixtures can lead to maintenance problems. You often forget to update them when you refactor your models. Other times, you have to try to fix them by hand and find yourself in a morass of primary keys. In general, they are fragile.
Many experts suggest that you forgo fixtures and write your own object factories. Great idea! Here is a tool to help you get started. Using the regular Django `dumpdata` command, pyfixtures will generate a python file that contains all the code necessary to re-constitute that data in an empty database. You can take that code and refactor it into something you maintain going forward, or you can re-generate it from a target database when needed.
# Install
### Add to INSTALLED_APPS
In your `settings.py`, add `pyfixtures` to the INSTALLED_APPS setting:
```python
INSTALLED_APPS = (
...
'pyfixtures',
)
```
### Set SERIALIZATION_MODULES
```bash
SERIALIZATION_MODULES = {'py': 'pyfixtures.serializer'}
```
# Usage
Use the regular Django dumpdata command, but with the format set to pyfixtures.
```bash
./manage.py dumpdata --exclude contenttypes --format=py > fixtures/initial_data.py
```
You can also use the `loaddata` command on that file, as you would expect.
```bash
./manage.py loaddata fixtures/initial_data.py
```
# Settings
```bash
PYFIXTURES_CIRCULAR_DEP_BREAKERS = ('Organization', 'Group', 'WorkflowHistory')
```
If you run into problems serializing your models due to circular dependencies, pyfixtures will prompt you to 'break the tie' by designating one or more of your models to use primary keys directly in the constructors.
You'll know if you need to use this setting if you see something like the following when you run dumpdata:
```bash
InfractionType depends on ['WorkflowItem']
WorkflowItem depends on ['WorkflowHistory']
WorkflowHistory depends on ['WorkflowItem']
Error: Unable to serialize database: Could not sort objects in dependency order, is there a circular dependency?
```
# Writing Your own Fixtures
The fixtures are mostly what you would expect. You import models that you need, and declare your objects. The fixtures that we generate don't use loops, but you can if you want to.
Because Django's `loaddata` command expects to save the models itself, we don't call `save()` on the models directly in the fixture. Instead, anything you define in the scope of the fixture file that inherits from Django's Model class will be saved when `loaddata` runs.
This is slightly at odds with how many to many relationships work in Django. Normally, you would structure your code like this:
```python
from django.db import models
class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
p1 = Publication(title='The Python Journal')
p1.save()
a1 = Article(headline='Django lets you build Web apps easily')
a1.publications.add(p1)
```
Because we need to defer the saving of your models, we use the following mechanism to declare many to many relationships. You should follow this convention if you write your own fixtures.
```python
p1 = Publication(title='The Python Journal')
a1 = Article(headline='Django lets you build Web apps easily')
a1.m2m_data = {'publications': [p1]}
```
Release historyRelease notifications
0.1.1
0.1
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Filename, size | File type | Python version | Upload date | Hashes |
---|---|---|---|---|
Filename, size django-pyfixtures-0.1.tar.gz (6.0 kB) | File type Source | Python version None | Upload date | Hashes |
Hashes for django-pyfixtures-0.1.tar.gz
Algorithm | Hash digest |
---|---|
SHA256 | ee58c90a537ab3af8bee682b93df6e7a3f39227e4acac050214410505b0b9621 |
MD5 | 9494476d72e80ab9227cc4c3e1122efc |
BLAKE2-256 | 3e78b17f3c3a8cc4d92ce48267c839707cb97bdd2d3342d9c0c266af719864b8 |
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upHave a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
commented Sep 10, 2013
Using Django 1.5, running ./manage.py dumpdata gives me:Not sure if this is explicitly linked to Django 1.5, but I haven't encountered it on other projects using 1.4... |
commented Sep 11, 2013
In order to make a logtail_log hyperlink appear within the admin interface, I added a Log model to the models.py containing managed = False within the model meta. Turns out that you're the first person to do a dumpdata on this application, exposing a flaw in the unmanaged-nonexistent-model method.The django consensus is that even unmanaged models should be dumped if someone runs the dumpdata command to dump every app. Sadly there's no wonderful do_not_dump (or do_not_load ) flags to be found in django model options. Therefore the only way round this for now is to do:Alternative way to do this I reckon would be to play around with the ModelAdmin class to see if I can define an edit link without it relating to a model. I'll get back to you about that. |
pushed a commit that referenced this issue Sep 11, 2013
commented Sep 11, 2013
(Nope) |
closed this Sep 11, 2013
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment