6

I am working on a Django project and made a model with several instances of a models.ForeignKey with the same Model.

class Country(models.Model):
    name = models.CharField(max_length=100)
    primary_language = models.ForeignKey('Language', related_name='primary_language', default="")
    secondary_language = models.ForeignKey('Language', related_name='secondary_language', default="")
    tertiary_language = models.ForeignKey('Language', related_name='tertiary_language', default="")

    def __str__(self):
        return self.name

This is the Language model:

class Language(models.Model):
    name = models.CharField(max_length=50)
    abbreviation = models.CharField(max_length=2)

    def __str__(self):
        return self.name

when doing $python3 manage.py makemigration baseit works fine, no errors. I have put the 2 migration files I think are the most important.

class Migration(migrations.Migration):

    dependencies = [
        ('base', '0002_country_country_code'),
    ]

    operations = [
        migrations.CreateModel(
            name='Currency',
            fields=[
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
                ('name', models.CharField(max_length=50)),
                ('abbreviation', models.CharField(max_length=3)),
            ],
        ),
        migrations.CreateModel(
            name='Language',
            fields=[
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
                ('name', models.CharField(max_length=50)),
                ('abbreviation', models.CharField(max_length=2)),
            ],
        ),
        migrations.AddField(
            model_name='country',
            name='phone_country_code',
            field=models.CharField(default='', max_length=7),
        ),
        migrations.AlterField(
            model_name='country',
            name='country_code',
            field=models.CharField(default='', max_length=2),
        ),
        migrations.AddField(
            model_name='country',
            name='primary_language',
            field=models.ForeignKey(to='base.Language', default=''),
        ),
        migrations.AddField(
            model_name='country',
            name='secondary_language',
            field=models.ForeignKey(related_name='secondary_language', to='base.Language', default=''),
        ),
        migrations.AddField(
            model_name='country',
            name='tertiary_language',
            field=models.ForeignKey(related_name='tertiary_language', to='base.Language', default=''),
        ),
    ]

class Migration(migrations.Migration):

    dependencies = [
        ('base', '0006_auto_20151023_0918'),
    ]

    operations = [
        migrations.AddField(
            model_name='country',
            name='primary_language',
            field=models.ForeignKey(default='', related_name='primary_language', to='base.Language'),
        ),
        migrations.AddField(
            model_name='country',
            name='secondary_language',
            field=models.ForeignKey(default='', related_name='secondary_language', to='base.Language'),
        ),
        migrations.AddField(
            model_name='country',
            name='tertiary_language',
            field=models.ForeignKey(default='', related_name='tertiary_language', to='base.Language'),
        ),
        migrations.AlterField(
            model_name='language',
            name='abbreviation',
            field=models.CharField(max_length=2),
        ),
        migrations.AlterField(
            model_name='language',
            name='name',
            field=models.CharField(max_length=50),
        ),
    ]

Now when running the migration I get an error message I can't figure out. I think these are the lines that matter in the stacktrace:

johan@johan-pc:~/sdp/gezelligehotelletjes_com$ python3 manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: auth, base, sessions, admin, contenttypes, hotel
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying base.0003_auto_20151023_0912...Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.IntegrityError: column "primary_language_id" contains null values


The above exception was the direct cause of the following exception:

django.db.utils.IntegrityError: column "primary_language_id" contains null values

First of all I do not have a column "primary_language_id" but I guess this is created by Django. Even when deleting the entire Language model and the lines for the languages in the Country model, I still get this error.

Could someone help me with figuring this out?

Johan Vergeer
  • 5,208
  • 10
  • 48
  • 105

2 Answers2

9

You already have Country objects in your database.

When you add the primary_language_id column to them (which represents the primary_language ForeignKey), those countries end up with an empty primary_language (because you didn't specify a default), which throws an error (because you didn't allow empty values either for primary_language).

The solution depends on how you want that migration to work. You can add blank = True to the primary_language ForeignKey definition, add a default, or you break down your migration in 3 migrations (add the column with blank = True, set values, remove blank = True).

Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116
  • Hi Thomas, thanks for the fast reply. When adding empty=True to the foreignkey defenition I get an error with makemigration, so that would not work. primary_language = models.ForeignKey('Language', related_name='primary_language', empty=True). I already added default="", and now I tried it with default=1, since I refer to ForeignKey which is represented by a number. This also doesn't work. – Johan Vergeer Oct 23 '15 at 10:39
  • 4
    @JohanVergeer sorry, it's `blank = True`, not `empty = True`. Make sure you **delete existing migrations and recreate them.** Otherwise your changes won't solve the migration problem (they'll just add more migrations to run afterwards, which won't help). – Thomas Orozco Oct 23 '15 at 10:40
  • I gave that a shot primary_language = models.ForeignKey('Language', related_name='primary_language', default=1) but did not work. Even when commenting out all the language lines in the Country model, I get the same error message. django.db.utils.IntegrityError: column "primary_language_id" contains null values – Johan Vergeer Oct 23 '15 at 10:45
  • @JohanVergeer Unless you deleted the migrations and re-ran `makemigrations`, your changes to the model won't make a difference. Did you do that? – Thomas Orozco Oct 23 '15 at 10:49
  • I have deleted all the migrations and reran makemigrations. This still did not work. So I just deleted the database and reinstalled it. Now it works again. – Johan Vergeer Oct 23 '15 at 11:05
  • @JohanVergeer I found after deleting migrations sometimes to avoid further deleting database and starting over I must run `db stamp head` – Bob Jordan Feb 09 '16 at 09:57
  • @ThomasOrozco thank you for mentioning to delete existing migrations. That is what I needed to do and it helped me solve my problem! – Clever Programmer Jun 06 '16 at 16:47
0

If you had a table created and it was populated, when you try to add it another column Django is like these data already in the table don't have this new field this guy is trying to add and it messes up. What I did was to go to my table and delete all the data. Once I did that I could migrate. If you have a small table this might work, no need to touch migrations.

Ray Rojas
  • 151
  • 1
  • 8