Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.9 - OperationalError: no such table: products_category_artists; due to ManyToManyField?

I tried Googling this problem, but I mostly saw answers that were from versions of Django where South was needed for migration and/or syncdb was still a thing. The ones that were relevant matched the symptom, but not the cause.

I started with the default project/app that Django creates when you do django-admin startproject project-name and django-admin startapp products.

models.py

from django.db import models
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist

# Create your models here.
class Artist(models.Model):
    user = models.OneToOneField(User, null=True, blank=True)
    
    name = models.CharField(max_length=50)
    
    def __str__(self): return "<Artist: %s>"%self.name

class Category(models.Model):
    artists = models.ManyToManyField(Artist)
    
    name = models.CharField(max_length=50)
    desc = models.CharField(max_length=200)

My process:

  • python manage.py flush to clear the database
  • rm -rf products\migrations to delete prior migrations
  • python manage.py migrate

Output:

Operations to perform:
  Apply all migrations: sessions, contenttypes, auth, admin
Running migrations:
  No migrations to apply.
  • python manage.py makemigrations products

Output:

Migrations for 'products':
  0001_initial.py:
    - Create model Artist
    - Create model Category
  • python manage.py migrate

Output:

Operations to perform:
  Apply all migrations: contenttypes, admin, sessions, products, auth
Running migrations:
  No migrations to apply.

At this point, I'm confused. Aren't there migrations to be applied, and yet there aren't any? I press on nonetheless.

  • python manage.py shell

In this shell, I enter these commands:

>>> from products.models import *
>>> artist = Artist(name="foo")
>>> artist.save()
>>> categ = Category(name="bar", desc="baz")
>>> categ.save()
>>> categ.artists.add(artist)

At this point, I get a huge error traceback. The problem seems to be this:

django.db.utils.OperationalError: no such table: products_category_artists

I see the same error if I try to use the built-in admin site.

My guess is that the problem is that migrations aren't actually being applied or that a particular table isn't being created, but I don't know how to fix either of these problems.

like image 670
El'endia Starman Avatar asked Sep 11 '25 13:09

El'endia Starman


1 Answers

There is a table generated by django called django_migrations which keeps track of what migrations have been applied. If you delete your migrations, re-generate them and try to migrate without deleting the records from the table than django will think it already applied them. You should never delete your migrations, it will cause django to get confused.

If you are actively developing and want to skip the entire migrations system you can, but once you start using migrations, never delete them. Here is what I use while developing a new project:

dropdb mydb && createdb mydb && python manage.py migrate --run-syncdb && python manage.py loaddata initial

First, it drops the database and all data. Then it creates an empty one. The --run-syncdb generates the schema and the loaddata loads data from a fixtures file.

So, if you are still developing and can delete all your data and move what you care about to a fixtures file than you can delete all your migration folders and run the command above each time you change your model.

like image 131
dotcomly Avatar answered Sep 13 '25 06:09

dotcomly