简体   繁体   English

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

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

I am getting the error我收到错误

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

when trying to do the initial migration for a django project with a new database that I'm deploying on the production server for the first time.在尝试使用我第一次在生产服务器上部署的新数据库对 django 项目进行初始迁移时。

I suspected the problem might be because one of the the apps had a directory full of old migrations from a SQLite3 development environment;我怀疑这个问题可能是因为其中一个应用程序的目录充满了来自 SQLite3 开发环境的旧迁移; I cleared those out but it didn't help.我清除了这些,但没有帮助。 I also searched and found references to people having the problem with multiple databases, but I only have one.我还搜索并找到了对多个数据库有问题的人的引用,但我只有一个。

Django version is 1.11.6 on python 3.5.4, mysqlclient 1.3.12 python 3.5.4、mysqlclient 1.3.12上的Django版本是1.11.6

Some considerations: 一些考虑:

  • Are you calling ContentType.objects manager anywhere in your code that may be called before the db has been built? 您是否在构建数据库之前调用的代码中的任何位置调用ContentType.objects管理器?
  • I am currently facing this issue and need a way to check the db table has been built before I can look up any ContentTypes 我目前正面临这个问题,需要一种方法来检查db表是否已经构建,然后才能查找任何ContentTypes

I ended up creating a method to check the tables to see if it had been created, not sure if it will also help you: 我最终创建了一个方法来检查表是否已创建,不确定它是否也会帮助您:

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

As for migrations, my understanding is that they should always belong in your version control repo, however you can squash, or edit as required, or even rebuild them, this linked helps me with some migrations problems: Reset Migrations 至于迁移,我的理解是它们应该始终属于您的版本控制仓库,但是您可以根据需要进行挤压或编辑,甚至重建它们,这个链接可以帮助我解决一些迁移问题: 重置迁移

Answering my own question: 回答我自己的问题:

UMDA's comment was right. UMDA的评论是正确的。 I have some initialization code for the django-import-export module that looks at content_types, and evidently I have never deployed the app from scratch in a new environment since I wrote it. 我有一些用于查看content_types的django-import-export模块的初始化代码,显然我从未在新环境中从头开始部署应用程序,因为我编写了它。

Lessons learned / solution: 经验教训/解决方案:

  • will wrap the offending code in an exception block, since I should only have this exception once when deploying in a new environment 将包含有问题的代码包装在异常块中,因为在新环境中部署时我只应该有一次此异常

  • test clean deployments in a new environment more regularly. 在更新的环境中更频繁地测试清洁部署。

    • (edit to add) consider whether your migrations directories belong in .gitignore . (编辑添加)考虑您的migrations目录是否属于.gitignore For my purposes they do. 为了我的目的,他们做到了

(Relatively new to stackoverflow etiquette - how do I credit UMDA's comment for putting me on the right track?) (相对较新的stackoverflow礼仪 - 我如何赞扬UMDA的评论让我走上正轨?)

I had the same issue when trying to create a generic ModelView (where the model name would be passed as a variable in urls.py ). 在尝试创建通用ModelView时,我遇到了同样的问题(模型名称将作为urls.py的变量传递)。 I was handling this in a kind of silly way: 我是以一种愚蠢的方式处理这个问题:

Bad idea: a function that returns a generic class-based view 不好的想法:一个返回基于类的通用视图的函数

views.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 urls.py

from django.urls import path, include

from my_app import views

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

Anyway. 无论如何。 Let's not dwell in the past. 我们不要忘记过去。

This was fixable by properly switching to a class-based view, instead of whatever infernal hybrid is outlined above, since (according to this SO post ) a class-based view isn't instantiated until request-time. 这可以通过适当地切换到基于类的视图来修复,而不是上面概述的任何地狱混合,因为(根据这个SO帖子 )基于类的视图直到请求时才被实例化。

Better idea: actual generic class-based view 更好的主意:实际的基于通用类的视图

views.py 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 urls.py

from django.urls import path, include

from my_app import views

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

May you make new and better mistakes. 愿你犯下新的更好的错误。

Chipping in because maybe this option will appeal better in some scenarios.插手是因为在某些情况下,这个选项可能会更有吸引力。

Most of the project's imports usually cascade down from your urls.py .大多数项目的导入通常从您的urls.py级联下来。 What I usually do, is wrap the urls.py imports in a try/except statement and only create the routes if all imports were successful.我通常做的是将urls.py导入包装在 try/except 语句中,并且仅在所有导入成功时才创建路由。

What this accomplishes is to create your project's / app's routes only if the modules were imported.这样做的目的是仅在导入模块时创建项目/应用程序的路由。 If there is an error because the tables do not yet exist, it will be ignored, and the migrations will be done.如果由于表尚不存在而出现错误,则将忽略该错误,并完成迁移。 In the next run, hopefully, you will have no errors in your imports and everything will run smoothly.在下一次运行中,希望您的导入没有错误,并且一切都会顺利进行。 But if you do, it's easy to spot because you won't have any URLs.但是如果你这样做了,它很容易被发现,因为你没有任何 URL。 Also, I usually add an error log to guide me through the issue in those cases.此外,我通常会添加一个错误日志来指导我解决这些情况下的问题。

A simplified version would look like this:简化版本如下所示:

# 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

Now, maybe you can combine Omar's answer for a more sensible, less catch-all solution.现在,也许您可​​以将 Omar 的答案结合起来,以获得更明智、更全面的解决方案。

暂无
暂无

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

相关问题 Django-MySQL:1146表不存在 - Django - MySQL : 1146 Table doesn't exist 从本地 sqlite3 迁移到 mysql:django.db.utils.ProgrammingError:(1146,“表''不存在”) - migrate from local sqlite3 to mysql : django.db.utils.ProgrammingError: (1146, “Table '' doesn't exist”) 错误1146:mysql Phpmyadmin中的表&#39;#__content&#39;不存在&#39; - Error 1146: table '#__content' doesn't exist' in mysql Phpmyadmin Django 编程错误 1146 表不存在 - Django programming error 1146 table doesn't exist Django 测试 django.db.utils.ProgrammingError:(1146,“表‘DB.Table’不存在”) - Django test django.db.utils.ProgrammingError: (1146, "Table 'DB.Table' doesn't exist") 找不到 django/mysql 表 - django.db.utils.ProgrammingError: (1146, &quot;表 &#39;trustline.authentication_user&#39; 不存在&quot;) - django/mysql table not found - django.db.utils.ProgrammingError: (1146, "Table 'trustline.authentication_user' doesn't exist") django-reversion:get_for_object()引发数据库错误“&#39; <db_name> .django_content_type&#39;不存在” - django-reversion: get_for_object() throws database error “'<db_name>.django_content_type' doesn't exist” 错误代码 1146 表 &#39;<table_name> &#39; 不存在 MySql 错误 - Error code 1146 Table '<table_name>' doesn't exist MySql error 备份后不存在MySQL错误1146表 - MySQL ERROR 1146 table doesn't exist after backup Python / MySQL:编程错误 1146 - 表不存在 - Python / MySQL : Programming error 1146 - Table doesn't exist
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM