I have a project written with Django 1.6 and that uses South migrations, and I trying to move it to Django 1.7. So I started from the instructions indicated here.
Deleted south from INSTALLED_APPS.
Removed old migrations files.
Ran ./manage.py makemigrations.
At this point I got django.db.migrations.graph.CircularDependencyError.
Here are my models:
customer.models.py:
class Customer(models.Model):
name = models.CharField(
max_length=128,
)
class Department(models.Model):
customer = models.ForeignKey(
'customer.Customer',
related_name='departments',
)
name = models.CharField(
max_length=64,
)
class Representative(models.Model):
user = models.ForeignKey(
'userprofile.User',
related_name='representatives',
)
department = models.ForeignKey(
'customer.Department',
related_name='representatives',
)
userprofile.models.py:
class User(AbstractBaseUser, PermissionsMixin):
customers = models.ManyToManyField(
'customer.Customer',
blank=True,
null=True,
)
That caused in initial migration for customer application a swappable dependency:
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
As it was recommended here, I edited initial migration for userprofile and commented lines related with customer:
class Migration(migrations.Migration):
dependencies = [
('auth', '0001_initial'),
#('customer', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('first_name', models.CharField(max_length=128, error_messages={b'min_length': 'El campo "Nombres" debe tener al menos %(limit_value)d caracteres (actualmente tiene %(show_value)d).'}, verbose_name='nombres', validators=[django.core.validators.MinLengthValidator(3)])),
('last_name', models.CharField(max_length=128, error_messages={b'min_length': 'El campo "Apellidos" debe tener al menos %(limit_value)d caracteres (actualmente tiene %(show_value)d).'}, verbose_name='apellidos', validators=[django.core.validators.MinLengthValidator(3)])),
('email', models.EmailField(unique=True, max_length=75, verbose_name='correo electr\xf3nico')),
#('customers', models.ManyToManyField(to='customer.Customer', null=True, verbose_name='clientes relacionados', blank=True)),
],
bases=(models.Model,),
),
]
ran ./manage.py migrate and created another migration that adds a customer field:
class Migration(migrations.Migration):
dependencies = [
('customer', '0001_initial'),
('userprofile', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='user',
name='customers',
field=models.ManyToManyField(to='customer.Customer', null=True, verbose_name='clientes relacionados', blank=True),
preserve_default=True,
),
]
But when I run ./manage.py migrate userprofile --fake, I get an error
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
On the other hand, without this migration my tests fail:
OperationalError: no such table: userprofile_user_customers
My error was to run ./manage.py makemigrations userprofile, instead of running ./manage.py makemigrations userprofile --empty. In the first case Django understood it like a migration that adds contracts field (which it is) and for the second case, if I ran ./manage.py migrate userprofile it fails with:
django.db.utils.ProgrammingError: relation "userprofile_user_customers" already exists
So I had to:
Copy the content of the last migration:
class Migration(migrations.Migration):
dependencies = [
('customer', '0001_initial'),
('userprofile', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='user',
name='customers',
field=models.ManyToManyField(to='customer.Customer', null=True, verbose_name='clientes relacionados', blank=True),
preserve_default=True,
),
]
Delete that migration.
Run ./manage.py makemigrations userprofile --empty.
Paste and run ./manage.py migrate userprofile --fake.
Related
models.py
class Country(models.Model):
name = models.CharField(max_length=50, validators=[validate_name, ])
class Meta:
managed = False
db_table = 'countries'
def __str__(self):
return self.name
0001_initial.py
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Country',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, validators=[countries.validators.validate_name])),
],
options={
'db_table': 'countries',
'managed': False,
},
),
]
sql
(venv) michael#michael:~/Documents/PyCharmProjects/db/db$ python manage.py sqlmigrate countries 0001_initial
BEGIN;
--
-- Create model Country
--
-- (no-op)
COMMIT;
Could you tell me whether this sql reflects the model or not? If not, how can it happen? And will it produce in the database?
There is no sql to apply to the db because of managed = False.
That is, running migrate does not change the db.
Python 3.10.4
Django 4.0.5
PostgreSQL 14
When I start "python manage.py makemigrations" i got the file "0001_initial.py" but all Fields, except autofields, are missing.
models.py
from django.db import models
# Create your models here.
class Username(models.Model):
#id = models.AutoField(primary_key=True)
username: models.CharField(max_length=100)
class Carrier(models.Model):
#id = models.AutoField(primary_key=True)
carriername: models.CharField(max_length=100)
desc: models.TextField()
0001_initial.py
# Generated by Django 4.0.5 on 2022-06-29 13:18
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Carrier',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
migrations.CreateModel(
name='Username',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
]
First, you must know that Django By default adds the id field to the models ...
Try to Delete the migration file and
you must use the = not the :
so it will be like this
class Username(models.Model):
username=models.CharField(max_length=100)
class Carrier(models.Model):
carriername = models.CharField(max_length=100)
desc = models.TextField()
rerun manage.py makemigrations and it Should work
I'm just wondering what the correct syntax is for calling $ python manage.py migrate app_name --database db_name with the management.call_command() function at runtime.
So far, I have the following:
from django.core import management
from django.core.management.commands import migrate
# Migrate the core.contrib.dynamics if needed to the pre-specified database:
management.call_command(migrate.Command(), 'dynamics', '--database {}'.format(DB_NAME))
However, I get the following error at runtime when calling the above:
Cannot find a migration matching '--database default_node' from app 'dynamics'.
I'm 99% sure I'm probably calling the -- args incorrectly? Can anyone point me in the right direction with this?
The migrations for the dynamics app are as follows:
# Generated by Django 3.0.8 on 2020-07-02 14:28
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ModelSchema',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True)),
('_modified', models.DateTimeField(auto_now=True)),
],
),
migrations.CreateModel(
name='FieldSchema',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=63)),
('data_type', models.CharField(choices=[('character', 'character'), ('text', 'text'), ('integer', 'integer'), ('float', 'float'), ('boolean', 'boolean'), ('date', 'date')], editable=False, max_length=16)),
('null', models.BooleanField(default=False)),
('unique', models.BooleanField(default=False)),
('max_length', models.PositiveIntegerField(null=True)),
('model_schema', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='dynamics.ModelSchema')),
],
options={
'unique_together': {('name', 'model_schema')},
},
),
]
Considering you already ran the migrations, you can simply use
management.call_command('migrate', app_label='dynamics', database='dbname')
I have the following issue:
I work on a Django app that has a primary DB and now we are adding a secondary DB for syncing only some of the data in it. When I tried to run the migrations, I got an error: null value in column 'field_2' violates not-null constraint. And here is the issue:
The model:
class A(models.Model):
field_1 = models.BooleanField(default=False)
field_2 = models.BooleanField(default=True) # added later
field_3 = models.BooleanField(default=True) # added later
and 4 migrations (well, more, but those don't count):
0001 - a related model is created
0002 - model A is created and the relation is created (ForeignKey)
0003 - field_2 is added to model A
0004 - field_3 is added to model A
However when I run migrate on the new DB, the migration stops at migration 0002 with the error mentioned above:
django.db.utils.IntegrityError: null value in column "field_2" violates not-null constraint
even though the field is created in a later migration.
I don't know hot to even begin a workaround this issue.
Edit:
Migration 0001:
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name='B',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('year', models.IntegerField()),
('active', models.BooleanField(default=True)),
],
)
]
Migration 0002:
class Migration(migrations.Migration):
dependencies = ['app', '0001']
operations = [
migrations.CreateModel(
name='A',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('field_1', models.BooleanField(default=False))
],
),
migrations.AddField(
model_name='b',
name='a',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.B'),
),
]
Migration 0003:
class Migration(migrations.Migration):
dependencies = ['app', '0002']
operations = [
migrations.AddField(
model_name='a',
name='field_2',
field=models.BooleanField(default=True),
),
]
Migration 0004:
class Migration(migrations.Migration):
dependencies = ['app', '0003']
operations = [
migrations.AddField(
model_name='a',
name='field_3',
field=models.BooleanField(default=True),
),
]
Migrated: 0001
THIS IS MY MODEL FILE
from django.db import models
class Donor(models.Model):
Donor_name = models.CharField(max_length=150),
Donor_status = models.IntegerField(),
Donor_city = models.CharField(max_length=50),
Donor_group = models.CharField(max_length=10),
Donor_phone = models.CharField(max_length=12),
Donor_mail = models.EmailField(max_length=50)
THIS IS MY MIGRATION
Generated by Django 2.0.2 on 2018-03-30 09:19
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Donor',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
)
Why are other fields ignored ?
using Django version 2 with MySQL.
The commas at the end of the lines cause Python to treat them as tuples. Remove them.
class Donor(models.Model):
Donor_name = models.CharField(max_length=150)
Donor_status = models.IntegerField()
Donor_city = models.CharField(max_length=50)
Donor_group = models.CharField(max_length=10)
Donor_phone = models.CharField(max_length=12)
Donor_mail = models.EmailField(max_length=50)
Once you have made this change, you can run makemigrations again and Django should include your new fields. If you haven't run the migration that creates the modlel yet, you could remove the migration file before doing this. You can use python manage.py showmigrations to check whether the migration has already been run.
Note that in Django, the recommendation is to use lowercase_with_underscores for your field names, e.g. donor_name and donor_status.