Question

So I was developing an app in Django and needed a function from the 1.4 version so I decided to update.
But then a weird error appeared when I wanted to do syncdb
I am using the new manage.py and as You can see it makes some of the tables but then fails :

./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'
Was it helpful?

Solution

I had the same issue, the definition for my custom field was missing the connection parameter.

from django.db import models

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

OTHER TIPS

Although already old, answered and accepted question but I am adding my understanding I have added it because I am not using customized type and it is a Django Evolution error (but not syncdb)evolve --hint --execute. I think it may be helpful for someone in future. .

I am average in Python and new to Django. I also encounter same issue when I added some new features to my existing project. To add new feature I had to add some new fields of models.CharField() type,as follows.

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) 

The Django version I am using is 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 is an extension to Django that allows you to track changes in your models over time, and to update the database to reflect those changes.

$ 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.

The trial was susses and when I tried to apply changes in 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'

To understand this exception I check that this exception is something similar to:

>>> 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'
>>> 

So the function signature has been changed.

Because I have not added any new customized or enum fields but only two similar fields that was already in model and char type field is supported by most of database (I am ussing PostgreSQL) even I was getting this error!

Then I read from @: Russell Keith-Magee-4 Reply.

What you've hit here is the end of the deprecation cycle for code that doesn't support multiple databases.

In Django 1.2, we introduced multiple database support; in order to support this, the prototype for get_db_preb_lookup() and get_db_prep_value() was changed.

For backwards compatibility, we added a shim that would transparently 'fix' these methods if they hadn't already been fixed by the developer.

In Django 1.2, the usage of these shims raised a PendingDeprecationWarning. In Django 1.3, they raised a DeprecationWarning.

Under Django 1.4, the shim code was been removed -- so any code that wasn't updated will now raise errors like the one you describe.

But I am not getting any DeprecationWarning warning assuming because of newer version of Django Evolution.

But from above quote I could understand that to support multiple databases function signature is added and an extra argument connection is needed. I also check the db_type() signature in my installation of Django as follows:

/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):
   :
   :

Ialso refer of Django documentation

Field.db_type(self, connection):

Returns the database column data type for the Field, taking into account the connection object, and the settings associated with it.

And Then I could understand that to resolve this issue I have to inherited models.filed class and overwrite def db_type() function. And because I am using PostgreSQL in which to create 300 chars type field I need to return 'char(300)'. In my models.py I added:

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

If you encounter similar problem please check your underline DB's manual that which type of column you need to create and return a string.

And changed the definition of new fields (that I need to add) read comments:

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) 

Then I executed same command that was failing previously:

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.

I also check my DB and tested my new added features It is now working perfectly, and no DB problem.

If you wants to create ENUM field read Specifying a mySQL ENUM in a Django model.

Edit: I realized instead of sub classing models.Field I should have inherit more specific subclass that is models.CharField.

Similarly I need to create Decimal DB fields so I added following class in model:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top