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)
…
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.
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.
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?
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!
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.