Error Message
django.db.utils.OperationalError: no such table: clientauth_tbltokentypes
What I am trying to do
I am trying to migrate data with table generation.
models.py
class tbltokentypes(models.Model):
token_type_id: AutoField(primary_key=True)
token_type: CharField(max_length=30)
I ran the command python manage.py makemigrations, which created the file 0001_initial.py.
Then in the migration file, I added managers:
from django.db import migrations, models
from clientauth.models import tbltokentypes
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='tbltokentypes',
fields=[
('token_type_id', models.AutoField(primary_key=True, serialize=False, verbose_name='token_type_id')),
('token_type', models.CharField(max_length=30)),
],
managers=[
tbltokentypes(token_type = "Registration").save()
]
)
]
Am I missing anything?
Wrap your function call in migrations.RunPython, otherwise it will be run while assigning operations, before the migration can even be run to create your table.
from django.db import migrations, models
# from clientauth.models import tbltokentypes # Remove this
# Add this function
def migrate_tbltokentypes(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
tbltokentypes = apps.get_model('clientauth', 'tbltokentypes')
tbltokentypes(token_type="Registration").save()
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='tbltokentypes',
fields=[
('token_type_id', models.AutoField(primary_key=True, serialize=False)),
('token_type', models.CharField(max_length=30)),
],
# managers=[ # Change this
# tbltokentypes(token_type = "Registration").save() #
# ] #
),
migrations.RunPython(migrate_tbltokentypes), # to this
]
Also note, from https://docs.djangoproject.com/en/3.2/topics/migrations/#data-migrations:
[Data migrations are] best written as separate migrations, sitting alongside your schema migrations.
python manage.py makemigrations --empty clientauth --name migrate_tbltokentypes
Related
As a proof of concept, I made these two migrations in the simplest possible Django app, polls.
Here is migration 0001.
# Generated by Django 4.0.5 on 2022-06-15 18:17
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Question',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('question_text', models.CharField(max_length=200)),
],
),
]
Here is migration 0002
# Generated by Django 4.0.5 on 2022-06-15 18:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('polls', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='question',
name='question_type',
field=models.CharField(max_length=200, null=True),
),
]
And here is the model.
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
question_type = models.CharField(max_length=200, null=True)
Let's say I've migrated the database, and now want to revert 0002. I run the following command python manage.py sqlmigrate polls 0002 --backwards and get this SQL
BEGIN;
--
-- Add field question_type to question
--
CREATE TABLE "new__polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL);
INSERT INTO "new__polls_question" ("id", "question_text") SELECT "id", "question_text" FROM "polls_question";
DROP TABLE "polls_question";
ALTER TABLE "new__polls_question" RENAME TO "polls_question";
COMMIT;
Clearly, it's dropping the entire column (by dropping and recreating the table), but I'm curious, could Django be made to keep that column without deleting it?
Unique Class or extend Class or Subclass in Python Django?
In the following situation, I have a feeling I need to ?extend? the Migration class instead of re-stating it in the second module. Or is a child class needed?
A goal here: To create a postgres table called venues. There is already a models/venues.py that seems to be set up ok.
migrations/0001_initial.py:
class Migration(migrations.Migration):
initial = True
dependencies = [('auth', '0012_alter_user_first_name_max_length'),]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, ...)),
('password', models.CharField(max_length=128, ...)),
...
migrations/0002_venue.py:
class Migration(migrations.Migration):
dependencies = [('app', '0001_initial'),]
operations = [
migrations.CreateModel(
name='Venue',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True...)),
('name', models.CharField(blank=True ...)),
('address', models.CharField(blank=True...)),
...
** models/venue.py:**
class Venue(models.Model):
name = models.CharField(blank=True, null=True...)
address = models.CharField(blank=True, null=True...)
city = models.CharField(blank=True, null=True, ...)
zip = models.CharField(blank=True, null=True...)
#gps_coords = models.CharField(blank=True...)
gps_lat = models.DecimalField(max_digits=14...)
gps_long = models.DecimalField(max_digits=14...)
description = models.TextField(blank=True, ...)
website = models.URLField(blank=True...)
contact_phone = models.CharField(blank=True...)
contact_email = models.EmailField(blank=True...)
contact_name = models.CharField(blank=True...)
def __str__(self):
return self.name + " " + self.description
Help?
Once you create your model class, you need to run python manage.py makemigrations and django will create a migration file. (Make sure you've added the app to the INSTALLED_APPS on project's settings.py
Once you run the makemigrations, you'll be able to see the migration file in your app's migrations folder. Having this file doesn't mean the table is created. It just represents the set of instructions that'll run on database when you run the migrate command.
When you have the new migration file, you can run python manage.py migrate, and that migration file will be applied to your database.
You can run the showmigrations command to see which migrations are applied on your database.
python manage.py showmigrations
or
python manage.py showmigrations app_name
I'm trying to add internal_code to a Django Model in the existing project.
internal_code = models.CharField(max_length=128, default=uuid.uuid4, unique=True)
The problem is that when running migrate, Django raises IntegrityError:
DETAIL: Key (internal_code)=(b24f1ca6-bd90-4c91-87b0-5f246a4057e1) is duplicated.
I understand that this problem exists only during migrate as it is generated just once.
Is there a way to avoid this behavior without having to do this?:
set field to null=True
migrate
add RunPython that will populate all the existing objects internal_code fields
set field to null=False
EDIT: This is the final migration file. I want to know if I can avoid writing such migration to get the same result (automatic so not touching shell)
from django.db import migrations, models
import uuid
def gen_uuid(apps, schema_editor):
Product = apps.get_model('products', 'Product')
for product in Product.objects.all():
product.my_sku = uuid.uuid4()
product.save(update_fields=['my_sku'])
class Migration(migrations.Migration):
dependencies = [
('products', '0015_auto_20210827_1252'),
]
operations = [
migrations.AddField(
model_name='product',
name='my_sku',
field=models.CharField(max_length=128, null=True),
),
migrations.RunPython(gen_uuid),
migrations.AlterField(
model_name='product',
name='my_sku',
field=models.CharField(default=uuid.uuid4, max_length=128, unique=True),
),
]
This is an easy exercise, i'm a beginner about models and migration
Models.py
from django.db import models
# Create your models here.
class Flight(models.Model):
origin = models.CharField(max_length=64),
destination = models.CharField(max_length=64),
duration = models.IntegerField()
Then i'm going on my prompt and type
python manage.py makemigrations
and in migrations/0001_initial.py
# Generated by Django 3.1.7 on 2021-03-23 16:19
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Flight',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('duration', models.IntegerField()),
],
),
]
How u can see origin and destination don't migrate
How can i fix it?
remove ',' now try makemigrations
class Flight(models.Model):
origin = models.CharField(max_length=64)
destination = models.CharField(max_length=64)
duration = models.IntegerField()
I use Django 1.10
school/models.py
class School(models.Model):
name = models.CharField(max_length=10,null=False)
school_id = models.CharField(max_length=8,null=False)
weather = models.ForeignKey(Weather,related_name="school")
When I modified the school class by adding eng_name = models.CharField(max_length=50,null=False)
I deleted the migrations file first.
And after running the command:
python manage.py makemigrations school
python manage.py migrate --fake-initial school
python manage.py migrate school
The messages both for the migrate are
Operations to perform:
Apply all migrations: school
Running migrations:
No migrations to apply.
But the database didn't update.
What is the possible reason to cause this issue?
UPDATAE
migrations/0001_initial.py
class Migration(migrations.Migration):
initial = True
dependencies = [
('weather', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='School',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=10)),
('eng_name', models.CharField(max_length=50)),
('school_id', models.CharField(max_length=8)),
('weather', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='school', to='weather.Weather')),
],
),
]
python manage.py showmigrations --plan
[X] weather.0001_initial
[X] school.0001_initial
These both are the latest migrate .
Django is storing applied migrations in database as table (django_migrations) with columns (id, app, name, applied). Just remove row with applied initial migration for "school" app then make migrate. And, in future, do not remove old transactions files. With them django will create properly named transactions for migration-mechanism.