Opened 4 years ago

Closed 4 years ago

#24248 closed Bug (worksforme)

django.db.utils.OperationalError: no such table: creating models from running manage.py inspectdb

Reported by: Richard Bruskiewich Owned by: nobody
Component: Documentation Version: 1.7
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Software Context: Django release 1.7

Issue: the interplay between the reverse engineering wrapping of legacy databases into Django models, further (1.7 South-style) migrations of those databases, and the regular expectations of (database) unit test development

The recommended general protocol for this is at https://docs.djangoproject.com/en/1.7/howto/legacy-databases/

Duly noted there is that the class Meta 'manage' attribute of generated models defaults to 'False'

What is not mentioned is that when one then runs 'manage.py makemigration ' on the models which have the manage flag set to 'False', that the necessary database 'CREATE' commands are NOT issued.

In hindsight, one realizes that the function of the manage flag set to 'False' is such to prevent Django from ever (re)creating the database table behind a model. The assumption here is that "if you already have a database, why recreate the tables?"

Fine...

The catch is that if you attempt to write unit tests against your database...

Django 1.7 dutifully attempts to (re-)create a test database in such a context. But, surprise! Since the necessary tables are not CREATEd in the test database, the unit test code to save model objects thus fails.

Solution:

Set the Meta.manage flag to 'True'. HOWEVER, it is generally recommended that you set the manage flag for all your models to 'True' before running the first makemigration operation, to avoid complications.

You can use the manage.py sqlmigrate command to see what happens if you do set this flag to 'True' after the first migration.

Interestingly, you always need to run makemigration twice to see the full effect of the change:

1) the first makemigration run reports that the change in the model's meta option, and

2) the second makemigration issues the creation command and may complain about the lack of default value settings for the 'not null' foreign keys in your model (you need to specify some).

The best idea seems to be to set all your model flags to 'False' before the first migration.

Caveat:

There are likely good reasons for having the Meta.manage flag of an existing database set to 'False', such as to prevent inadvertent modification (or even loss) of the tables of a legacy database. Such considerations may dictate some caution in this task (i.e. make sure you have a good backup copy of the legacy database somewhere in case something goes wrong...).

The above issues probably merits deeper consideration by the Django developers' community to forge out clearer 'best practices' for the task, against the need to enable proper database migrations and unit testing...). For example, perhaps some way of getting the migration process to issue a "CREATE ... IF NOT EXISTS" command in legacy contexts may be helpful, rather than just the simple "CREATE " which the current Django migration appears to produce, might be helpful.

Change History (2)

comment:1 Changed 4 years ago by Markus Holtermann

Component: MigrationsDocumentation

From what I understand, this isn't a particular problem of migrations but a lack in documentation. If you feel strongly about the issue I'd suggest to post to the django-developers mailing list.

comment:2 Changed 4 years ago by Tim Graham

Resolution: worksforme
Status: newclosed

The requirement to create database tables during test setup for unmanaged models is already documented: "For tests involving models with managed=False, it’s up to you to ensure the correct tables are created as part of the test setup."

Please open a thread on the DevelopersMailingList as Markus suggested if you wish to revisit this design decision.

Note: See TracTickets for help on using tickets.
Back to Top