Postgresql, Django 2.0, Python 3.6.4
After running a migration that changed the name of a field desktop_pay to simply pay, I'm getting an error when running manage.py test saying the column pay does not exist.
Here's the migration:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('instructions', '0055_auto_20180517_1508'),
]
operations = [
migrations.RenameField(
model_name='instruction',
old_name='desktop_pay',
new_name='pay',
),
]
Here's the error:
> python .\manage.py test
Creating test database for alias 'default'...
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: column instructions_instruction.pay does not exist
LINE 1: "...on"."quota", "instructions_instruction"."target", "instructi...
^
If I start a psql prompt, though, I can clearly see that the column does exist, at least in the "real" table.
mydatabase=> \d+ instructions_instruction
Table "public.instructions_instruction"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
---------------------+------------------------+-----------+----------+------------------------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('instructions_instruction_id_seq'::regclass) | plain | |
quota | smallint | | not null | | plain | |
pay | numeric(5,2) | | not null | | main | |
### etc...
What's going on here? Why is Django not finding the column? How can I debug this?
I've faced this problem too. First of all, I couldn't got why this errors only appears while testing.
Then I looked into traceback and saw that Django fails to run one of my migration not related to column Django can't find.
It was manually written migration to populate objects uuid field with autogenerated values. I import model Post just as usual.
import uuid
from django.db import migrations
from posts.models import Post
def gen_uuid(apps, schema_editor):
for post in Post.objects.all():
post.uuid = uuid.uuid4()
post.save(update_fields=["uuid"])
class Migration(migrations.Migration):
dependencies = [
("posts", "0014_post_uuid"),
]
operations = [
migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
]
I don't clearly understand why, but this code breaks migrations while preparing testing database (and works fine outside of testing mode). So any following migrations do not apply to testing database and that cause column does not exist error.
So what to do? Use apps.get_model instead of it as described in official Django docs on writing migrations https://docs.djangoproject.com/en/3.1/howto/writing-migrations/#migrations-that-add-unique-fields.
Something like this.
import uuid
from django.db import migrations
def gen_uuid(apps, schema_editor):
Post = apps.get_model("posts", "Post")
for post in Post.objects.all():
post.uuid = uuid.uuid4()
post.save(update_fields=["uuid"])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With