从 South 迁移到 Django 1.7 迁移:可交换依赖
Moving from South to Django 1.7 migrations: swappable dependency
我有一个用 Django 1.6 编写的项目,它使用 South 迁移,我试图将它移动到 Django 1.7。所以我从 here.
指示的说明开始
- 已从
INSTALLED_APPS
中删除 south
。
- 删除了旧的迁移文件。
- 运行
./manage.py makemigrations
.
此时我得到了django.db.migrations.graph.CircularDependencyError
。
这是我的模型:
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,
)
这在 customer
应用程序的初始迁移中导致了可交换的依赖项:
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
根据建议 here,我编辑了 userprofile
的初始迁移并注释了与客户相关的行:
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,),
),
]
运行 ./manage.py migrate
并创建了另一个添加客户字段的迁移:
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,
),
]
但是当我运行./manage.py migrate userprofile --fake
时,我得到一个错误
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.
另一方面,如果没有此迁移,我的测试会失败:
OperationalError: no such table: userprofile_user_customers
我的错误是运行./manage.py makemigrations userprofile
,而不是运行宁./manage.py makemigrations userprofile --empty
。在第一种情况下,Django 将其理解为添加 contracts
字段(确实如此)的迁移,对于第二种情况,如果我 运行 ./manage.py migrate userprofile
它失败并显示:
django.db.utils.ProgrammingError: relation "userprofile_user_customers" already exists
所以我不得不:
复制上次迁移的内容:
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,
),
]
删除那个迁移。
- 运行
./manage.py makemigrations userprofile --empty
.
- 粘贴并运行
./manage.py migrate userprofile --fake
。
我有一个用 Django 1.6 编写的项目,它使用 South 迁移,我试图将它移动到 Django 1.7。所以我从 here.
指示的说明开始- 已从
INSTALLED_APPS
中删除south
。 - 删除了旧的迁移文件。
- 运行
./manage.py makemigrations
.
此时我得到了django.db.migrations.graph.CircularDependencyError
。
这是我的模型:
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,
)
这在 customer
应用程序的初始迁移中导致了可交换的依赖项:
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
根据建议 here,我编辑了 userprofile
的初始迁移并注释了与客户相关的行:
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,),
),
]
运行 ./manage.py migrate
并创建了另一个添加客户字段的迁移:
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,
),
]
但是当我运行./manage.py migrate userprofile --fake
时,我得到一个错误
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.
另一方面,如果没有此迁移,我的测试会失败:
OperationalError: no such table: userprofile_user_customers
我的错误是运行./manage.py makemigrations userprofile
,而不是运行宁./manage.py makemigrations userprofile --empty
。在第一种情况下,Django 将其理解为添加 contracts
字段(确实如此)的迁移,对于第二种情况,如果我 运行 ./manage.py migrate userprofile
它失败并显示:
django.db.utils.ProgrammingError: relation "userprofile_user_customers" already exists
所以我不得不:
复制上次迁移的内容:
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, ), ]
删除那个迁移。
- 运行
./manage.py makemigrations userprofile --empty
. - 粘贴并运行
./manage.py migrate userprofile --fake
。