Makemigration fail - no such table - during active development

Recently, I’m refactoring my code to add a new field to a model. After adding the new field, I went to “makemigrations” and starting getting failures. After numerous attempts at trying to fix, I decided to use a hammer:

I deleted db.sqllite3 to re-create. I was not able to resolve the problem with creating a new DB. I then removed all my migrations files and the db.sqllite3 file to create anew.

Now, when I attempt to “makemigrations” from scratch, I’m getting a “no such table” from a reference in forms.py to a model that should be created in migrations. However, it’s a chicken-before-egg problem. I need to create a migration file to create the table, but makemigrations fails because there’s no table?

How can I solve for this? Thanks!

Django 4.2.2
Python 3.9.6

python manage.py makemigrations batchthis
… [snipped]…
File “/Users/aaronpaxson/PycharmProjects/webroot/batchthis/forms.py”, line 48, in
class BatchAddForm(forms.Form):
File “/Users/aaronpaxson/PycharmProjects/webroot/batchthis/forms.py”, line 54, in BatchAddForm
size_units = forms.ChoiceField(choices=units, required=True)
…[snipped]…
django.db.utils.OperationalError: no such table: batchthis_unit

snipped forms.py

from .models import Unit
units = Unit.objects.filter(category=Unit.VOLUME).values_list(‘id’,‘name’)
size_units = forms.ChoiceField(choices=units, required=True)

If you’re creating a new database, you need to run the current migrations before doing a makemigrations to create new migrations.

Edit: ah it’s below that, yes please don’t do module level db access.

File “/Users/aaronpaxson/PycharmProjects/webroot/batchthis/forms.py”, line 54, in BatchAddForm
size_units = forms.ChoiceField(choices=units, required=True)

What’s units here? Is it a materialised queryset? If so then that’s a no-no (module-level aka import time db access). Probably only just got highlighted now after truncating your db.

Running “migrate” or “makemigrations” results in the same problem.

“Unit” is a model. “units” is a list of filtered Unit items.

forms.py
units = Unit.objects.filter(category=Unit.VOLUME).values_list(‘id’,‘name’)

Is that line in a method or function within forms.py, or is it module level code? If it’s at the module level (not within a function), then that’s what’s causing the error.

Unfortunately, I may not be saavy enough to know the difference. I have a form that leverages data in a model (table) called Units:

forms.py (snipped)

from .models import Unit

class BatchAddForm(forms.Form):
    units = Unit.objects.filter(category=Unit.VOLUME).values_list('id','name')
    fermenters_ready = Fermenter.objects.filter(vessel__status=Vessel.STATUS_READY).values_list('id','vessel__name')
    name = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Name of Batch'}),required=True)
    startdate = forms.DateField(label="Start Date",widget=NumberInput(attrs={'type':'date'}),required=True)
    size = forms.IntegerField(widget=forms.TextInput(attrs={'placeholder':'Size of batch'}),required=True)
    size_units = forms.ChoiceField(choices=units, required=True)

Now, we are picking on “Unit” here, because it’s the first that’s found as an error. If I remove/comment it out, another model/table is found to be “not found”.

I believe it’s because I can’t initialize the database with the tables, because I’m getting an error saying “table not found”?

I realize I used a hammer here, where I probably could have been more surgical (i.e not removing my DB and migrations), but I’ve had so many changes, I thought it would be cleaner to start with a fresh migration list. I’m now regretting that.

A form defined fields - you don’t use queries for form fields.

So no, those two lines for units and fermenters_ready aren’t valid.

I’m not sure what you’re trying to do with those two lines, but whatever it is, this isn’t the way to do it.

No, that’s not correct. You’ve got cause & effect reversed. You can’t run migrations because those two statements aren’t correct.

hmmmm, I may need to re-read the docs. I have a form that displays only active fermenters. In order to do that, I have to query which fermenters are active to give a valid choice. It was working perfectly fine until I wiped the DB.

So, If I’m not supposed to make model query/filters in my form choices, I’m guessing I move that logic my views? That’s all I need to do?

No, you need to reread the forms docs regarding choices for select fields.

See ChoiceField and ModelChoiceField along with the links in those sections of the docs.

You can also search the forums here for similar topics - this is an area that has been discussed here fairly frequently.

Thanks @KenWhitesell . i’ll read up. I appreciate it. I have a feeling that’s what @shangxiao was also telling me, but wasn’t following. The docs are great, but knowing the “why” isn’t always there.

You can tell I code until it doesn’t work, then read/learn, and continue coding. I imagine this was never a problem for me, since the table did exist by the time I wrote this.

A lot of the “whys” you are likely encountered are “because Python does it that way”. It’s really tough to understand forms, models, etc, unless you have a really firm understanding of how Python works with classes and modules.

The Django docs do assume a degree of proficiency with Python.

I’m pretty proficient with Python (well, subjective to me, anyway. I’m not a full-time developer, but often enough). Been doing it off-and-on for years, since I dropped Java and EJBs back in 2007.

What I didn’t consider, was that Django’s “makemigration” was far more than just “map model to DB”. I didn’t realize it compiled all of the project and validating. I thought it was a simple command that manages the diff for the database, and creates the necessary SQL to build the schema.

I’m used to more abstraction where I can call queries from anywhere, I wasn’t intending to give a negative feedback on the docs. But, knowing why lazy calls were important here would have been neat. LOL

All good. I’ll refactor my forms knowing this. As I said, it wasn’t a problem for a long time, since the table was there with data while I’ve been coding. Glad I wiped the DB then to catch this. Thanks for the help!

That’s actually not a valid statement.

The makemigration command imports your models.py files in the apps that are managed by migrations. (There may be some other imports as well, I’m not entirely sure.)

Any other side effects occur as a result of those imports.