我正在做一个Django项目,目前使用的是第三方应用Oscar。我们正在从Oscar迁移到一个定制的商店,为此,我们希望摆脱一堆旧文件,模型,当然还有实际的第三方依赖关系。但我很难做到这一点,因为迁移文件不断抛出错误。
情况是,我们有第一方模型,依赖于奥斯卡的模型。举例来说:
from oscar.apps.catalogue.models import Product
class Executable(Model):
exec_hash = CharField(max_length=64, unique=True)
product = ForeignKey(Product, blank=True, null=True, on_delete=CASCADE)
version = CharField(max_length=32)
os = CharField(max_length=32)
update_url = CharField(max_length=128, blank=True)
这意味着我们有一个迁移文件,其中包含创建此表的代码:
migrations.CreateModel(
name="Executable",
fields=[
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("exec_hash", models.CharField(max_length=64, unique=True)),
("version", models.CharField(max_length=32)),
("os", models.CharField(max_length=32)),
("update_url", models.CharField(blank=True, max_length=128)),
(
"product",
models.ForeignKey(
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="catalogue.product"
),
),
],
),
需要删除此Executable
中的product
字段,因此我从模型中删除了该字段并创建了一个新的迁移。
现在,我想从INSTALLED_APPS
列表中删除所有Oscar应用程序,但这会引起很多麻烦,因为当我想创建或运行任何迁移时,我会收到以下错误:
ValueError: The field sr_app.Executable.product was declared with a lazy reference to 'catalogue.product', but app 'catalogue' isn't installed.
我试着从初始迁移文件中简单地删除这个字段,但是在下一次迁移中(这个字段实际上是从模型中删除的),我得到了一个关键错误:
Running migrations:
Applying sr_app.0003_remove_executable_product...Traceback (most recent call last):
[...snip...]
File "/Users/kevin/Workspace/my_project_name/.venv/lib/python3.10/site-packages/django/db/migrations/operations/fields.py", line 162, in state_forwards
old_field = model_state.fields.pop(self.name)
KeyError: 'product'
因此,似乎我必须永远安装Oscar和INSTALLED_APPS
的一部分,因为初始迁移使用此信息?但是第一次迁移已经被应用了,所以第一次迁移需要在下一次迁移运行时有效,这有点烦人。
我怎样才能解决这个问题?当我自己的初始迁移依赖于Oscar(或任何第三方应用程序)时,我如何摆脱该第三方应用程序?
3条答案
按热度按时间u4dcyp6a1#
我在我的项目中也遇到过类似的情况。我尝试过压缩迁移,但遇到了循环依赖的问题,我还没有解决。
话虽如此,您可能希望尝试压缩迁移(请参阅https://docs.djangoproject.com/en/4.2/topics/migrations/#squashing-migrations),因为这将解决您的问题-一旦您的生产部署更新到这些压缩的迁移点,您就可以删除旧的迁移,然后一旦从项目及其迁移中删除了对应用程序的所有引用,您就可以从
INSTALLED_APPS
中删除应用程序。简而言之,你运行
./manage.py squashmigrations
和你想要压缩的应用程序和迁移数量,Django将尝试通过删除在以后的迁移中添加然后删除的字段来优化迁移。0h4hbjxa2#
旧的迁移是出于兼容性的原因,如果您在不同的位置有多个版本的数据库状态,则需要它们(即,e.开发和生产服务器、开发人员个人电脑等)
如果您确定没有人使用尚未迁移的旧版本,则不需要旧的迁移。因此,只需确保在此项目中工作的每个人都迁移到最新版本的代码库,运行此代码的每个服务器也迁移,并从头开始重新创建迁移(删除所有迁移并创建新的)。
另一种解决方法是在旧的迁移中伪造此表:编辑第一次迁移,以这种方式引入与第三方表的关系,以便在数据库中创建相同的模型,并确保下一次迁移使用此假模型而不是第三方模型。然后编辑删除该关系的最新迁移,以便也删除伪模型。这也可能奏效。
6tdlim6h3#
我最近不得不从Django项目中的第三方应用程序迁移,并在迁移文件和依赖项方面遇到了类似的挑战。以下是我如何成功做到的:
第一步:创建新的字段删除迁移
您需要从我的Executable模型中删除一个字段(产品),该模型依赖于Oscar的“目录”应用程序。为此,您应该专门为此更改创建一个新迁移:
在这个新的迁移中,您应该从Executable模型中删除product字段。
第二步:更新迁移文件中的权限
在新的迁移文件(例如0003_remove_executable_product.py)中,您必须更新依赖项。有一行字是这样的:
您应该删除依赖于'catalogue'的行,因为您必须删除依赖于它的字段。
第三步:从已安装的LED_APPS中删除“catalogue”
现在安全地从Django项目设置中的Paddle_APPS列表中删除“catalogue”。
步骤4:应用迁移
最后,再次运行迁移以应用更改:
第5步:清理奥斯卡专用代码
随着“catalogue”应用程序和产品字段依赖项的删除,您可以开始清理项目中任何其他奥斯卡特定的代码。
通过遵循这些步骤,您将很有可能能够安全地从项目中删除“目录”应用程序(Oscar),而不会遇到“惰性引用”错误。请记住备份您的数据并使用版本控制(例如Git)来跟踪此过程中的更改。此外,在删除第三方依赖项时要小心,因为它可能会影响项目的其他部分。