views:

21

answers:

2

I am relatively new to django. I have defined my db schema and validated it with no errors (manage.py validate reports 0 errors found).

Yet when I run ./manage.py syncdb

I get the following stack trace:

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

I have checked (and double checked) my table schema. All name field are CharField type with maximum length = 64. The backend db I am using is MySQL, so I am sure that indexes can be created for strings of length 64.

What could be causing this error (I suspect it is a misleading error message - even though its coming from the db itself)...

A: 

The traceback is happening during the creation of a django.contrib.auth.Permission: some of these get created for your models automatically as part of syncdb.

Permission.name has max_length=50, so you probably have an application and/or model class with a really long name?

Try the following query in manage.py dbshell:

SELECT * FROM auth_permission WHERE LENGTH(name) = 50;
Piet Delport
@Piet: brilliant diagnosis!. How did you work out that the exception was being thrown during the creation of django.contrib.auth.Permission ? (I cant see that in the stack trace). In any case, I run the SQL statement you suggested (one row was returned), and indeed I saw that one of the model names has been truncated. How may I fix this?
skyeagle
The stacktrace references this code: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/management/__init__.py#L28 , which is creating an object in the Permission model, belonging to the auth application (and thus the auth_permission table).
Craig Trader
Thanks for the clarification
skyeagle
Right: reading the function names, `create_permissions` stands out. Unfortunately, there's no real way to fix this except to shorten the affected name: a Django bug should probably be filed, to increase the name length and/or implement hashing of the excess.
Piet Delport
A: 

As Piet Delport noted, the problem is that your model name is too long.

You're certainly going to have to shorten your model name, and then clean up your database. How you do that depends upon where you are in the development process.

  • If this is a brand new application, with a dedicated database, and no actual data, the simple answer is to drop and recreate the database, and then re-run python manage.py syncdb.

  • If you have other tables in the database that need to be left alone, but the tables for your Django have no 'real' data, and can thus be dropped without damage, then you can use manage.py sqlclear to generate SQL DDL to drop all of the Django-generated tables, constraints, and indexes.

    Do the following:

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

    You can feed the generated script to mysql or python manage.py dbshell. Once that's done, you can re-run python manage.py syncdb.

  • If you have actual data in your database tables that can't be dropped or deleted: Slap yourself and repeat 100 times "I will never do development against a production database again. I will always back up my databases before changing them." Now you're going to have to hand-code SQL to change the affected table name, as well as anything else that references it and any references in the auth_permissions table and any other Django system tables. Your actual steps will depend entirely upon the state of your database and tables.

Craig Trader
Thanks for the advice (I am not working on a production db BTW ;) ). I had already done what you suggested -(from Piers post), before you posted it. But thanks for your help anyhow. I would vote your answer up, as it at least confirmed what I did - but I am prevented from doing so (asking for a login)
skyeagle