繁体   English   中英

Django MySQL 错误(1146,“表 'db_name.django_content_type' 不存在”)

[英]Django MySQL Error (1146, "Table 'db_name.django_content_type' doesn't exist")

我收到错误

django.db.utils.ProgrammingError: (1146, "Table 'db_name.django_content_type' doesn't exist")

在尝试使用我第一次在生产服务器上部署的新数据库对 django 项目进行初始迁移时。

我怀疑这个问题可能是因为其中一个应用程序的目录充满了来自 SQLite3 开发环境的旧迁移; 我清除了这些,但没有帮助。 我还搜索并找到了对多个数据库有问题的人的引用,但我只有一个。

python 3.5.4、mysqlclient 1.3.12上的Django版本是1.11.6

一些考虑:

  • 您是否在构建数据库之前调用的代码中的任何位置调用ContentType.objects管理器?
  • 我目前正面临这个问题,需要一种方法来检查db表是否已经构建,然后才能查找任何ContentTypes

我最终创建了一个方法来检查表是否已创建,不确定它是否也会帮助您:

def get_content_type(cls):
    from django.contrib.contenttypes.models import ContentType
    from django.db import connection

    if 'django_content_type' in connection.introspection.table_names():
        return ContentType.objects.get_for_model(cls)
    else:
        return None

至于迁移,我的理解是它们应该始终属于您的版本控制仓库,但是您可以根据需要进行挤压或编辑,甚至重建它们,这个链接可以帮助我解决一些迁移问题: 重置迁移

回答我自己的问题:

UMDA的评论是正确的。 我有一些用于查看content_types的django-import-export模块的初始化代码,显然我从未在新环境中从头开始部署应用程序,因为我编写了它。

经验教训/解决方案:

  • 将包含有问题的代码包装在异常块中,因为在新环境中部署时我只应该有一次此异常

  • 在更新的环境中更频繁地测试清洁部署。

    • (编辑添加)考虑您的migrations目录是否属于.gitignore 为了我的目的,他们做到了

(相对较新的stackoverflow礼仪 - 我如何赞扬UMDA的评论让我走上正轨?)

在尝试创建通用ModelView时,我遇到了同样的问题(模型名称将作为urls.py的变量传递)。 我是以一种愚蠢的方式处理这个问题:

不好的想法:一个返回基于类的通用视图的函数

views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.views.generic.edit import DeleteView


def get_generic_delete_view(model_name):
     model_type = ContentType.objects.get(app_label='myapp', model=model_name)

     class _GenericDelete(LoginRequiredMixin, DeleteView):
         model = model_type.model_class()
         template_name = "confirm_delete.html"

     return _GenericDelete.as_view()

urls.py

from django.urls import path, include

from my_app import views

urlpatterns = [
    path("mymodels/<name>/delete/", views.get_generic_delete_view("MyModel"),
]

无论如何。 我们不要忘记过去。

这可以通过适当地切换到基于类的视图来修复,而不是上面概述的任何地狱混合,因为(根据这个SO帖子 )基于类的视图直到请求时才被实例化。

更好的主意:实际的基于通用类的视图

views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.views.generic.edit import DeleteView

class GenericDelete(LoginRequiredMixin, DeleteView):
    template_name = "confirm_delete.html"

    def __init__(self, **kwargs):
        model = kwargs.pop("model")
        model_type = ContentType.objects.get(app_label='myapp', model=model)
        self.model = model_type.model_class()
        super().__init__()

urls.py

from django.urls import path, include

from my_app import views

urlpatterns = [
    path("mymodels/<name>/delete/", views.GenericDelete.as_view(model="MyModel"),
]

愿你犯下新的更好的错误。

插手是因为在某些情况下,这个选项可能会更有吸引力。

大多数项目的导入通常从您的urls.py级联下来。 我通常做的是将urls.py导入包装在 try/except 语句中,并且仅在所有导入成功时才创建路由。

这样做的目的是仅在导入模块时创建项目/应用程序的路由。 如果由于表尚不存在而出现错误,则将忽略该错误,并完成迁移。 在下一次运行中,希望您的导入没有错误,并且一切都会顺利进行。 但是如果你这样做了,它很容易被发现,因为你没有任何 URL。 此外,我通常会添加一个错误日志来指导我解决这些情况下的问题。

简化版本如下所示:

# Workaround to avoid programming errors on greenfield migrations
register_routes = True
try:
    from myapp.views import CoolViewSet
    # More imports...
except Exception as e:
    register_routes = False
    logger.error("Avoiding creation of routes. Error on import: {}".format(e))

if register_routes:
    # Add yout url paterns here

现在,也许您可​​以将 Omar 的答案结合起来,以获得更明智、更全面的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM