【问题标题】:Django syncdb exception after updating to 1.4更新到 1.4 后的 Django syncdb 异常
【发布时间】:2012-04-30 06:08:25
【问题描述】:

所以我在 Django 中开发了一个应用程序,需要 1.4 版本的功能,所以我决定更新。
但是当我想做syncdb
时出现了一个奇怪的错误 我正在使用新的manage.py,正如您所看到的,它制作了一些表格,但随后失败了:

./manage.py syncdb
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
Traceback (most recent call last):
  File "./manage.py", line 9, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 196, in run_from_argv
self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 371, in handle
    return self.handle_noargs(**options)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/commands/syncdb.py", line 91, in handle_noargs
    sql, references = connection.creation.sql_create_model(model, self.style,     seen_models)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/backends/creation.py", line 44, in sql_create_model
    col_type = f.db_type(connection=self.connection)
TypeError: db_type() got an unexpected keyword argument 'connection'

【问题讨论】:

  • 我发现错误是由我使用的自定义 EnumField 引起的(对于所有将出现相同错误的人)
  • 感谢您跟进您的问题 :)
  • 你做了什么来克服这个问题?您是否修改了 EnumField 课程?如果是这样,你做了什么?
  • 在读到 MySQL 数据库不支持该字段后,我删除了该字段。我添加了一个带有选项的 smallIntegerField:models.SmallIntegerField(choices=PLATFORM_CHOICES, blank=True, default=5)PLATFORM_CHOICES=( (1, 'iOS'), (2, 'MAC'), (3, 'iPhone'), (4, 'iPad'), (5, 'Universal'), )
  • @JakubSzymion 应该发布答案..

标签: django updating django-syncdb


【解决方案1】:

我遇到了同样的问题,我的自定义字段的定义缺少连接参数。

from django.db import models

class BigIntegerField(models.IntegerField):
    def db_type(self, connection):
        return "bigint"

【讨论】:

    【解决方案2】:

    虽然问题已经很老了,已回答并已接受,但我补充了我的理解,我添加了它,因为我没有使用自定义类型,它是 Django Evolution 错误(但不是 syncdb)evolve --hint --execute。我认为这可能对将来的某人有所帮助。 .

    我的 Python 水平一般,并且是 Django 新手。当我向现有项目添加一些新功能时,我也遇到了同样的问题。要添加新功能,我必须添加一些 models.CharField() 类型的新字段,如下所示。

    included_domains = models.CharField(
         "set of comma(,) seprated list of domains in target emails", 
         default="",           
         max_length=it_len.EMAIL_LEN*5) 
    excluded_domains = models.CharField(
        "set of comma(,) seprated list of domains NOT in target emails", 
        default="",               
        max_length=it_len.EMAIL_LEN*5) 
    

    我使用的Django版本是1.3.1:

    $ python -c "import django; print django.get_version()"
    1.3.1  <--------# version  
    
    $python manage.py syncdb
    Project signature has changed - an evolution is required
    

    Django Evolution:Django Evolution 是 Django 的一个扩展,它允许您跟踪模型随时间的变化,并更新数据库以反映这些变化。

    $ python manage.py evolve --hint 
    #----- Evolution for messagingframework
    from django_evolution.mutations import AddField
    from django.db import models
    
    
    MUTATIONS = [
        AddField('MessageConfiguration', 'excluded_domains', models.CharField, initial=u'', max_length=300),
        AddField('MessageConfiguration', 'included_domains', models.CharField, initial=u'', max_length=300)
    ]
    #----------------------
    Trial evolution successful.
    Run './manage.py evolve --hint --execute' to apply evolution.
    

    试验很糟糕,当我尝试在 DB 中应用更改时

    $ python manage.py evolve --hint --execute
    Traceback (most recent call last):
      File "manage.py", line 25, in <module>
        execute_manager(settings)
      File "/var/www/sites/www.taxspanner.com/django/core/management/__init__.py", line 362, in execute_manager
        utility.execute()
      File "/var/www/sites/www.taxspanner.com/django/core/management/__init__.py", line 303, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/var/www/sites/www.taxspanner.com/django/core/management/base.py", line 195, in run_from_argv  
        self.execute(*args, **options.__dict__)
      File "/var/www/sites/www.taxspanner.com/django/core/management/base.py", line 222, in execute
        output = self.handle(*args, **options)
      File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/management/commands/evolve.py", line 60, in handle
        self.evolve(*app_labels, **options)
      File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/management/commands/evolve.py", line 140, in evolve
        database))
      File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/mutations.py", line 426, in mutate
        return self.add_column(app_label, proj_sig, database)
      File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/mutations.py", line 438, in add_column
        sql_statements = evolver.add_column(model, field, self.initial)
      File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/db/common.py", line 142, in add_column
        f.db_type(connection=self.connection),  # <===  here f is field class object
    TypeError: db_type() got an unexpected keyword argument 'connection'
    

    为了理解这个异常,我检查了这个异常是否类似于:

    >>> def f(a):
    ...  print a
    ... 
    >>> f('b', b='a')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: f() got an unexpected keyword argument 'b'
    >>> 
    

    因此函数签名已更改。

    因为我没有添加任何 新的自定义或枚举 字段,但大多数数据库(我正在使用 PostgreSQL)只支持模型和字符类型字段中已经存在的两个类似字段,即使我是收到此错误!

    然后我从@阅读:Russell Keith-Magee-4 Reply

    您在这里遇到的是代码的弃用周期结束 不支持多个数据库。

    在 Django 1.2 中,我们引入了多数据库支持;为了 支持这个,get_db_preb_lookup() 的原型和 get_db_prep_value() 已更改。

    为了向后兼容,我们添加了一个垫片,可以透明地 “修复”这些方法,如果它们还没有被 开发商。

    在 Django 1.2 中,这些 shim 的使用引发了 未决弃用警告。在 Django 1.3 中,他们提出了一个 弃用警告。

    在 Django 1.4 下,shim 代码已被删除——所以任何代码 未更新现在会引发像您描述的错误。

    但我没有收到任何 DeprecationWarning 警告,假设是因为 Django Evolution 版本较新。

    但是从上面的引用我可以理解,为了支持多个数据库,函数签名被添加并且需要一个额外的参数connection。我还在安装 Django 时检查了db_type() 签名,如下所示:

    /django$ grep --exclude-dir=".svn" -n 'def db_type(' * -R 
    contrib/localflavor/us/models.py:8:    def db_type(self):
    contrib/localflavor/us/models.py:24:    def db_type(self):
       :
       :
    

    我也参考了 Django 文档

    Field.db_type(self, connection):

    返回字段的数据库列数据类型,考虑到连接 对象,以及与之关联的设置。

    然后我可以理解,要解决这个问题,我必须继承 models.filed 类并覆盖 def db_type() 函数。因为我使用的是PostgreSQL in which to create 300 chars type field,所以我需要返回'char(300)'。在我的 models.py 中,我添加了:

    class CharMaxlengthN(models.Field):
        def db_type(self, connection):
            return 'char(%d)' % self.max_length  # because I am using postgresql  
    

    如果您遇到类似问题,请查看您的下划线数据库手册,了解您需要创建哪种类型的列并返回一个字符串。

    并更改了新字段的定义(我需要添加)读取 cmets:

    included_domains = CharMaxlengthN( # <--Notice change 
          "set of comma(,) seprated list of domains in target emails", 
          default="",           
          max_length=it_len.EMAIL_LEN*5) 
    excluded_domains = CharMaxlengthN( # <-- Notice change
         "set of comma(,) seprated list of domains NOT in target emails", 
         default="",               
         max_length=it_len.EMAIL_LEN*5) 
    

    然后我执行了之前失败的相同命令:

    t$ python manage.py evolve --hint --execute
    
    You have requested a database evolution. This will alter tables
    and data currently in the None database, and may result in
    IRREVERSABLE DATA LOSS. Evolutions should be *thoroughly* reviewed
    prior to execution.
    
    Are you sure you want to execute the evolutions?
    
    Type 'yes' to continue, or 'no' to cancel: yes
    Evolution successful.
    

    我还检查了我的数据库并测试了我的新增功能它现在运行良好,没有数据库问题。

    如果您想创建 ENUM 字段,请阅读 Specifying a mySQL ENUM in a Django model

    编辑:我意识到我应该继承更具体的子类models.CharField,而不是子类models.Field

    同样我需要创建十进制数据库字段,所以我在模型中添加了以下类:

    class DecimalField(models.DecimalField):
        def db_type(self, connection):
            d = {
                'max_digits': self.max_digits,
                'decimal_places': self.decimal_places,
            } 
            return 'numeric(%(max_digits)s, %(decimal_places)s)' % d
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-18
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2011-11-27
      相关资源
      最近更新 更多