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

时间:2017-10-10 20:19:16

标签: mysql django

我收到错误

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

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

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

Django版本在python 3.5.4上是1.11.6,mysqlclient 1.3.12

4 个答案:

答案 0 :(得分:3)

一些注意事项:

  • 您是否在构建数据库之前调用的代码中的任何位置调用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

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

答案 1 :(得分:1)

回答我自己的问题:

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

经验教训/解决方案:

  • 会将违规代码包装在异常块中,因为我应该这样做 在新环境中部署时只有一次此异常

  • 更频繁地在新环境中测试干净部署。

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

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

答案 2 :(得分:0)

在尝试创建通用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"),
]

无论如何。让我们不要过去。

通过适当地切换到基于类的视图(而不是上面概述的任何地狱杂种),可以解决此问题,因为(根据this SO post),直到请求时才实例化基于类的视图。 / p>

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

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"),
]

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

答案 3 :(得分:0)

加入,因为此选项在某些情况下可能会更好地吸引人。

大多数项目的导入通常从您的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的答案,以获得更明智,更全面的解决方案。