添加信号接收器后,Django 从头开始​​迁移失败:“没有这样的表”

2024-05-04

我在代码中添加了一些信号接收器,一切都工作正常,直到我将其推送到版本控制并且 CI/CD 管道失败。在尝试迁移时,它会抱怨:

django.db.utils.OperationalError: no such table: badges_badge

但迁移正在我的机器上进行!

CI/CD 从头开始​​,所以我尝试删除我的db.sqlite3本地,然后尝试重新迁移python manage.py migrate:

 django.db.utils.OperationalError: no such table: badges_badge

因此,从现有数据库迁移是可行的,但从新数据库迁移则不行。

My signals.py:

from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver

from badges.badge_stuff import badges


@receiver(post_save)
def update_badges(sender, **kwargs):
    for badge in badges:
        badge.update()

My apps.py:

from django.apps import AppConfig


class BadgesConfig(AppConfig):
    name = 'badges'

    def ready(self):
        # Register signal listeners.
        from . import signals

为什么它可以与现有数据库一起使用,但在初始化时却不起作用?如何解决这个问题?


我遇到了这个问题,这是因为我注册信号的方式所致。

问题是代码中apps.ready()在任何迁移之前运行,所以如果signals.py取决于数据库中尚不存在的模型(例如,从头开始迁移时),它会失败。当您的signals.py导入其他模块,然后取决于您的模型。

Here, badges.badge_stuff.badges进口Badge模型,这是在第一次迁移时创建的。所以它找不到它。

为了解决这个问题,我们可以使用post_migrate信号来注册我们所有的信号after任何迁移,因此将在任何信号代码运行之前创建任何必要的模型。

将上面修改为:

from django.apps import AppConfig
from django.core.signals import pre_save, post_migrate


class BadgesConfig(AppConfig):
    name = 'badges'

    def register_signals(self, **kwargs):
        # If your signals are decorated with @receiver, the line below is all you need
        from . import signals
        # Otherwise, explicitly connect the signal handler
        pre_save.connect(signals.my_callback)

    def ready(self):
        post_migrate.connect(self.register_signals, sender=self)

希望运行您的迁移现在应该可以正常工作!

请记住在以下位置注册您的应用程序INSTALLED_APPS使用这个新的 AppConfigsettings.py:

INSTALLED_APPS = [
    ...
    'badges.apps.BadgesConfig',
    # Or just 'badges' for Django 4.0+
    ...
]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

添加信号接收器后,Django 从头开始​​迁移失败:“没有这样的表” 的相关文章

随机推荐