0

In a live web app, I have the following models (abridged):

class Ad(models.Model):
    name = models.CharField(max_length=50)
    apps = models.ManyToManyField(App, null=True, blank=True)

class App(models.Model):
    name = models.CharField(max_length=50)

I have the following tables (in my staging environment):

sqlite> .tables
auth_group
auth_group_permissions
auth_permission
auth_user
auth_user_groups
auth_user_user_permissions
django_admin_log
django_content_type
django_flatpage
django_flatpage_sites
django_migrations
django_session
django_site
myapp_app
myapp_ad

I no longer want Ad to have a ManyToMany relation to App, so I removed apps from Ad.

Then, I ran:

env/bin/python manage.py makemigrations

It produced this migration:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0035_auto_20150818_1302'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='ad',
            name='apps',
        ),
    ]

Then, I ran:

env/bin/python manage.py migrate

The migration fails with the following error:

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

I imagine that this is because I'm doing something wrong with the behind-the-scenes many to many table created for me when I first used the ManyToMany field. How can I alter my migration so that it succeeds?

bfox
  • 274
  • 2
  • 13
  • 1
    Can you provide list of tables from your database? – GwynBleidD Aug 18 '15 at 20:26
  • @GwynBleidD I updated my question with a list of tables, thanks! – bfox Aug 18 '15 at 22:04
  • 3
    Seems like your table was missing to begin with, maybe because you faked the migration that would've created it or because you manually removed it from the database. You can fake this new migration and everything will be fine. On a side note: South is the pre-1.7 external migrations app, using the term "South migrations" for new-style migrations can be quite confusing. – knbk Aug 18 '15 at 22:24
  • Thanks GwynBleidD for pointing me in the right direction and @knbk for the solution and nomenclature improvement. Both faking the migration, or creating a table of that name manually, fixed it locally, and the live server wasn't missing the table. – bfox Aug 18 '15 at 23:24

1 Answers1

2

The comments on my question led me to two solutions.

Solution from GwynBleidD's comment:

To get a shell on my staging environment's SQLite database, I ran:

env/bin/python manage.py dbshell

To list the tables in my staging environment, I ran:

sqlite> .tables

I noted that the table that the Django migration was complaining about, myapp_ad_apps, was indeed missing.

Still in the DB shell, I ran:

sqlite> CREATE TABLE myapp_ad_apps(
    ... ID INT PRIMARY KEY     NOT NULL,
    ... );

Then, I re-ran the migration, and it succeeded (and removed the table I just created).

Solution from knbk's comment:

To run the migration as fake, I ran:

env/bin/python manage.py migrate --fake

This also fixed the problem, independent of the first solution.

bfox
  • 274
  • 2
  • 13