【问题标题】:mysql exception when synchronizing db with django's manage.py script将 db 与 django 的 manage.py 脚本同步时出现 mysql 异常
【发布时间】:2010-10-06 22:09:44
【问题描述】:

我对 django 比较陌生。我已经定义了我的数据库架构并验证它没有错误(manage.py validate 报告发现 0 个错误)。

当我运行 ./manage.py syncdb

我得到以下堆栈跟踪:

Creating table demo_foobar_one
Creating table demo_foobar_two
<snip>...</snip>
Traceback (most recent call last):
  File "manage.py", line 11, in <module>
    execute_manager(settings)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 218, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 347, in handle
    return self.handle_noargs(**options)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/commands/syncdb.py", line 103, in handle_noargs
    emit_post_sync_signal(created_models, verbosity, interactive, db)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/sql.py", line 185, in emit_post_sync_signal
    interactive=interactive, db=db)
  File "/usr/local/lib/python2.6/dist-packages/django/dispatch/dispatcher.py", line 162, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/auth/management/__init__.py", line 28, in create_permissions
    defaults={'name': name, 'content_type': ctype})
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 135, in get_or_create
    return self.get_query_set().get_or_create(**kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 373, in get_or_create
    obj.save(force_insert=True, using=self.db)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 435, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 528, in save_base
    result = manager._insert(values, return_id=update_pk, using=using)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 195, in _insert
    return insert_query(self.model, values, **kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 1479, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 783, in execute_sql
    cursor = super(SQLInsertCompiler, self).execute_sql(None)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 727, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.6/dist-packages/django/db/backends/util.py", line 15, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.6/dist-packages/django/db/backends/mysql/base.py", line 86, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python2.6/dist-packages/MySQL_python-1.2.3-py2.6-linux-i686.egg/MySQLdb/cursors.py", line 176, in execute
    if not self._defer_warnings: self._warning_check()
  File "/usr/local/lib/python2.6/dist-packages/MySQL_python-1.2.3-py2.6-linux-i686.egg/MySQLdb/cursors.py", line 92, in _warning_check
    warn(w[-1], self.Warning, 3)
_mysql_exceptions.Warning: Data truncated for column 'name' at row 1

我已检查(并仔细检查)我的表架构。所有名称字段都是 CharField 类型,最大长度 = 64。我使用的后端数据库是 MySQL,所以我确信可以为长度为 64 的字符串创建索引。

可能导致此错误的原因(我怀疑这是一个误导性错误消息 - 即使它来自数据库本身)...

【问题讨论】:

标签: django django-models


【解决方案1】:

在创建django.contrib.auth.Permission 期间会发生回溯:其中一些会作为syncdb 的一部分自动为您的模型创建。

Permission.namemax_length=50,所以您可能有一个名称很长的应用程序和/或模型类?

manage.py dbshell 中尝试以下查询:

SELECT * FROM auth_permission WHERE LENGTH(name) = 50;

如果您无法更改模型名称,则可以通过在模型元类中指定verbose_name 来减少生成的Permission.name 的长度来解决此问题(有关详细信息,请参阅here):

class MyVeryLongModelNameThatIsBreakingMyMigration(models.Model):
    class Meta:
        verbose_name = 'my long model'

更新

有一个开放的(截至 2013 年)Django 票可以解决这个问题:

【讨论】:

  • 出色的诊断!您是如何确定在创建 django.contrib.auth.Permission 期间抛出异常的? (我在堆栈跟踪中看不到)。无论如何,我运行了您建议的 SQL 语句(返回了一行),实际上我看到其中一个模型名称已被截断。我该如何解决这个问题?
  • 堆栈跟踪引用此代码:code.djangoproject.com/browser/django/trunk/django/contrib/auth/…,它在权限模型中创建一个对象,属于 auth 应用程序(因此属于 auth_permission 表)。
  • 右:读取函数名称,create_permissions 脱颖而出。不幸的是,除了缩短受影响的名称之外,没有真正的方法可以解决这个问题:可能应该提交一个 Django 错误,以增加名称长度和/或实现多余的散列。
  • 我继承了一些有同样问题的代码。我无法使用 syncdb 创建数据库,因为某些模型名称太长。令人沮丧的是,这些相同的模型正在生产中工作,所以
【解决方案2】:

正如Piet Delport 所说,the problem is that your model name is too long

您当然必须缩短模型名称,然后清理数据库。如何做到这一点取决于您在开发过程中所处的位置。

  • 如果这是一个全新的应用程序,具有专用数据库,并且没有实际数据,简单的答案是删除并重新创建数据库,然后重新运行python manage.py syncdb

    李>
  • 如果您在数据库中有其他表需要单独放置,但您的 Django 表没有“真实”数据,因此可以删除而不会损坏,那么您可以使用manage.py sqlclear 生成 SQL DDL删除所有 Django 生成的表、约束和索引。

    执行以下操作:

    apps="auth contenttypes sessions sites messages admin <myapp1> <myapp2>"
    python manage.py sqlclear ${apps} > clear.sql
    

    您可以将生成的脚本提供给mysqlpython manage.py dbshell。完成后,您可以重新运行python manage.py syncdb

  • 如果您的数据库表中有无法删除或删除的实际数据:打自己一巴掌并重复 100 次 “我永远不会针对生产数据库进行开发再次。我将始终在更改数据库之前备份我的数据库。”现在您将不得不手动编写 SQL 来更改受影响的表名,以及引用它的任何其他内容auth_permissions 表和任何其他 Django 系统表中的任何引用。您的实际步骤将完全取决于您的数据库和表的状态。

【讨论】:

  • 感谢您的建议(顺便说一句,我不在生产数据库上工作;))。在您发布之前,我已经完成了您的建议 - (来自 Piers 帖子)。但无论如何感谢您的帮助。我会投票赞成你的回答,因为它至少证实了我所做的 - 但我被阻止这样做(要求登录)
  • 我知道这已经过时了,但是当我们唯一改变的是冗长的名称时,为什么还要删除任何表呢?我假设手动更新几个截断的名称字段可以做到这一点而不会删除任何内容,因为这不会影响任何 ID/代号。 PS您假设如果某人有他们不想在生产数据库中丢失的数据,这意味着他们正在直接在该环境中进行开发。 9/10 次并非如此,人们最终会启动他们的项目并关心数据,这就是我们使用迁移工具而不是 syncdb 的原因。
【解决方案3】:

我在使用 postgresql django 1.2 时也遇到了类似的错误,但问题不在于长度,而在于使用 ugettext_lazy 翻译名称。 ('can_purge', _("Can purge")) 显然是不可接受的,因为名称以文本形式存储在数据库中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2011-10-01
    • 2020-07-02
    相关资源
    最近更新 更多