Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a new database for an existing App using Django South and set default values?

I'm working with an OS project that uses South to migrate the database. I'm building a new database from scratch and I want to make sure South is setup so I can easily update the database in the future.

It seems this process should be:

  1. create the db
  2. syncdb
  3. migrate

However, when I try to migrate the databases, one of the the earlier migrations(migration 0004 and they go to 0009) throws an exception:

ValueError: You cannot add a null=False column without a default value.

I don't understand how to add a default value to migration 0004 so this exception isn't thrown.

The migrations don't need to be run through because the database is empty.

However, south_migrationhistory must contain a list of all migrations and when they were applied.

I tried to hack it and just add migration 0009 to the database manually, but this threw another error because the intermediary migrations had not been run. I also tried to add a field to database to see if I could figure out the syntax of add_column would look like with a default value of 0 supplied. The format looks totally different than these older migrations.

Here are the 2 different versions of the add_column syntax:

#0004 syntax:  
db.add_column('experiments_dailyreport', 'test_group_size', orm['experiments.dailyreport:test_group_size'])
#0009 syntax:
syntax db.add_column('experiments_dailyreport', 'test_group_size', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)

So, I'm guessing there was a change in the South code between when 0004 was created and today.

Is there a way to build the database with syncdb and then somehow update south_migrationhistory without running manage.py migrate ?

If you have an existing app with South migrations, how would you build a new database from scratch?

I can't migrate because there is no default set on a integer field. How do I set a default in an older migration? The field doesn't even exist anymore.

syntaxes attempted:

db.add_column('experiments_dailyreport', 'test_group_size', orm['experiments.dailyreport:test_group_size'], {'default': 0})
#throws ValueError: You cannot add a null=False column without a default value.
db.add_column('experiments_dailyreport', 'test_group_size', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
#throws AttributeError: Migration instance has no attribute 'gf'

I'm using South-0.7.2-py2.7.egg

like image 513
BryanWheelock Avatar asked Nov 12 '10 14:11

BryanWheelock


People also ask

What is the default database backend for Django projects when they are first set up?

By default, the configuration uses SQLite. If you're new to databases, or you're just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won't need to install anything else to support your database.

How does Django automatically create database?

Django doesn't create databases for you automatically. You have to do this yourself manually. This is a simple package that creates your database for you automatically, if necessary, when you run migrate for the first time. Important: This package only supports PostgreSQL at the moment!


2 Answers

Andrew Godwin provided an answer:

Yes, use:

./manage.py syncdb --all  

then:

./manage.py migrate --fake  

This will, however, also ignore any migrations that add in data to the database.

like image 51
BryanWheelock Avatar answered Sep 29 '22 23:09

BryanWheelock


syncdb is no longer supported, instead, see this answer:

  1. Delete all the folders named 'migrations'.
  2. Go to terminal and run:
  • ./manage.py makemigrations
  • ./manage.py migrate --run-syncdb
like image 23
nak Avatar answered Sep 30 '22 00:09

nak