I'm working on Django 1.9 and python 3.3 project using multiple databases (different schema in a same postgresql database). When I try to migrate the project for the first time, I'm getting this error
Running migrations:
Rendering model states... DONE
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying MyApp.0001_initial...Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: ERROR: relation "auth_user" does not exist
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/usr/lib/python3.4/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
utility.execute()
File "/usr/lib/python3.4/site-packages/django/core/management/__init__.py", line 342, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python3.4/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/lib/python3.4/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/usr/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/usr/lib/python3.4/site-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/usr/lib/python3.4/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/usr/lib/python3.4/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/usr/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 90, in __exit__
self.execute(sql)
File "/usr/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 110, in execute
cursor.execute(sql, params)
File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/lib/python3.4/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: ERROR: relation "auth_user" does not exist
This error seems to appeard in other projects when the auth_user table isn't migrated. In my case beginning my migration with manage.py migrate auth before migrating the app who need it doesn't solve the problem.
I suspect that the problem come from the use of different database in Django. My auth_user table is stored in the default database and the content of the models.py is routed to an other database.
Is the migration process looking for the auth_user table in the same database than my app database? Is it something absolutely different?
Answer to the problem
It is in fact a cross database reference problem. Django can't create cross database foreign keys.
From the Django 1.8 documentation (and there isn't any solution in the next versions (current version is 1.10)) :
Cross-database relations
Django doesn’t currently provide any support for foreign key or
many-to-many relationships spanning multiple databases. If you have
used a router to partition models to different databases, any foreign
key and many-to-many relationships defined by those models must be
internal to a single database.
This is because of referential integrity. In order to maintain a
relationship between two objects, Django needs to know that the
primary key of the related object is valid. If the primary key is
stored on a separate database, it’s not possible to easily evaluate
the validity of a primary key.
If you’re using Postgres, Oracle, or MySQL with InnoDB, this is
enforced at the database integrity level – database level key
constraints prevent the creation of relations that can’t be validated.
However, if you’re using SQLite or MySQL with MyISAM tables, there is
no enforced referential integrity; as a result, you may be able to
‘fake’ cross database foreign keys. However, this configuration is not
officially supported by Django
How to workaround and keep separate databases
In my case, because router are working, there is a little hack to simplify the cross database objects.
class CrossDBUser(models.Model):
user = models.IntegerField()
def get_user(self):
return User.objects.get(id=self.user)
def set_user(self, user):
self.user = user.id
class MyClassWithCrossDB(CrossDBUser):
field1 = models.CharField(max_length=200, blank=False)
field2 = models.IntegerField(default=0)
With this I can use the method set_user and get_user to work with the user stored in my object MyClassWithCrossDB.
Of course it's not perfect because it doesn't allow automated actions like on_delete=models.CASCADE and I'm obliged to work with methods instead of the instance variable. But it is a solution to workaround.
Related
I am trying to restrict GFK to be pointed to objects of a few models only, and I thought CheckConstraint will be a great way to do this, however I get this error
class ManualAdjustment(Model):
content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(null=True)
booking_obj = GenericForeignKey('content_type', 'object_id')
# should point to a app1.Booking1 or app2.Booking2 or app3.Booking3 only - trying to enforce this via CheckConstraint
class Meta:
constraints = [
models.CheckConstraint(
check=
Q(content_type__app_label='app1', content_type__model='booking1') |
Q(content_type__app_label='app2', content_type__model='booking2') |
Q(content_type__app_label='app3', content_type__model='booking3'),
name='myconstraint_only_certain_models'),
]
Error I get on migrate
execute_from_command_line(sys.argv)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/commands/sqlmigrate.py", line 30, in execute
return super().execute(*args, **options)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/commands/sqlmigrate.py", line 64, in handle
sql_statements = executor.collect_sql(plan)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/migrations/executor.py", line 225, in collect_sql
state = migration.apply(state, schema_editor, collect_sql=True)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/migrations/migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/migrations/operations/models.py", line 827, in database_forwards
schema_editor.add_constraint(model, self.constraint)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 343, in add_constraint
sql = constraint.create_sql(model, self)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/constraints.py", line 47, in create_sql
check = self._get_check_sql(model, schema_editor)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/constraints.py", line 37, in _get_check_sql
where = query.build_where(self.check)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1296, in build_where
return self._add_q(q_object, used_aliases=set(), allow_joins=False, simple_col=True)[0]
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1312, in _add_q
current_negated, allow_joins, split_subq, simple_col)
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
split_subq=split_subq, simple_col=simple_col,
File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1199, in build_filter
raise FieldError("Joined field references are not permitted in this query")
django.core.exceptions.FieldError: Joined field references are not permitted in this query
Any clue on how to solve this? I have used GFK before but with new checkconstraint it actually now can be a nicely error-safe way, if I could get this to migrate
Thanks
It is not possible to achieve this using the CheckConstraint functionality. Django translates all ORM commands to the low level DB specific commands, and such constraint creation isn't possible even on the DB level. In fact, we can apply CheckConstraint to a single row being added/updated only.
The note in documentation on PostgreSQL says:
PostgreSQL does not support CHECK constraints that reference table data other than the new or updated row being checked. While a CHECK constraint that violates this rule may appear to work in simple tests, it cannot guarantee that the database will not reach a state in which the constraint condition is false (due to subsequent changes of the other row(s) involved). This would cause a database dump and reload to fail. The reload could fail even when the complete database state is consistent with the constraint, due to rows not being loaded in an order that will satisfy the constraint. If possible, use UNIQUE, EXCLUDE, or FOREIGN KEY constraints to express cross-row and cross-table restrictions.
If what you desire is a one-time check against other rows at row insertion, rather than a continuously-maintained consistency guarantee, a custom trigger can be used to implement that. (This approach avoids the dump/reload problem because pg_dump does not reinstall triggers until after reloading data, so that the check will not be enforced during a dump/reload.)
So, the only way to introduce desired constrains is using db triggers. You can create empty migration and add DB trigger into it.
I have tried using ./manage.py migrate app_name zero command which was proposed but i keep on getting errors after i run python manage.py migrate testapp. My last solution would be to go to mysql drop entire db
Operations to perform:
Apply all migrations: testapp
Running migrations:
Rendering model states... DONE
Applying testapp.0001_initial...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\core\management\__init__.py", line 353,
_line
utility.execute()
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\core\management\__init__.py", line 345,
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\core\management\base.py", line 348, in
self.execute(*args, **cmd_options)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\core\management\base.py", line 399, in
output = self.handle(*args, **options)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\core\management\commands\migrate.py", l
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\migrations\executor.py", line 92, in
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\migrations\executor.py", line 121, i
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\migrations\executor.py", line 198, i
state = migration.apply(state, schema_editor)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\migrations\migration.py", line 123,
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\migrations\operations\models.py", li
rds
schema_editor.create_model(model)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\backends\base\schema.py", line 284,
self.execute(sql, params or None)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\backends\base\schema.py", line 110,
cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\backends\utils.py", line 79, in exec
return super(CursorDebugWrapper, self).execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\backends\utils.py", line 64, in exec
return self.cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\backends\utils.py", line 62, in exec
return self.cursor.execute(sql)
File "C:\Python27\lib\site-packages\django-1.9.7-py2.7.egg\django\db\backends\mysql\base.py", line 112, i
return self.cursor.execute(query, args)
File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
django.db.utils.OperationalError: (1050, "Table 'testapp_cinfo' already exists")
You are applying an initial migration, which means that you are creating the first version of that app’s tables.
But you already have that table in the database so you can fake the initial migration
python manage.py migrate --fake-initial
The --fake-initial flag to migrate was added in Django 1.8. Previously, Django would always automatically fake-apply initial migrations if it detected that the tables exist.
But note that this only works given two things:
You have not changed your models since you made their tables (which you have).
You have not manually edited your database.
So you can't fake them either.
I Want to use the current database
If you have your previous unaltered version of initial migration files of the testapp with migration(non-initial) files with your changes, you can use them for migration.
First fake that initial migration and then apply your changes
(This may be tricky now, as you also have to truncate django_migrations table that stores migrations data)
I can start from scratch -
No Problem (drop your database) as its an initial migration and that's what they are for - Create DB/Table.
If you already have tables in your db, try ./manage.py flush to clear all data. Flush carries out the SQL Drops on the entire db.
If you want to delete the db, drop the mysql db. Create another mysql db with the same name. Then run ./manage.py makemigrations followed by ./manage.py migrate to recreate the tables in the db.
models.py
class Stop(models.Model):
idn = models.PositiveIntegerField(primary_key=True, unique=True)
label = models.CharField(null=False, blank=False, max_length=512)
coor_x = models.FloatField()
coor_y = models.FloatField()
buses = models.ManyToManyField(Bus)
latest_query_datetime = models.DateTimeField(default=datetime(2000, 1, 1, 0, 0, 0))
latest_query_data = JSONField(default={})
class Meta:
ordering = ["label"]
def __str__(self):
return self.label
When I run:
python3 manage.py makemigrations && python3 manage.py migrate
It raises a ProgrammingError saying that jsonb datatype does not exist:
Migrations for 'rest':
0007_auto_20160612_1301.py:
- Alter field latest_query_data on stop
Operations to perform:
Apply all migrations: contenttypes, rest, auth, sessions, admin
Running migrations:
Rendering model states... DONE
Applying rest.0005_auto_20160612_1237...Traceback (most recent call last):
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: type "jsonb" does not exist
LINE 1: ... TABLE "rest_stop" ADD COLUMN "latest_query_data" jsonb DEFA...
^
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/core/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/migrations/migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards
field,
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 396, in add_field
self.execute(sql, params)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 110, in execute
cursor.execute(sql, params)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/erayerdin/.venv/eshot-api/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: type "jsonb" does not exist
LINE 1: ... TABLE "rest_stop" ADD COLUMN "latest_query_data" jsonb DEFA...
I use PostgreSQL to use JSONField and update it when a user requests a view. If I do not use default={}, it tells me to make one.
Further Analysis
I changed latest_query_data field to TextField so that I can store as string and convert to dict when I need. However, this also raised the same error.
Environment
django 1.9.6
psycopg 2.6.1
According to the Django docs, JSONField requires PostgreSQL ≥ 9.4 and Psycopg2 ≥ 2.5.4
What PostgreSQL version are you using?
See https://docs.djangoproject.com/en/dev/ref/contrib/postgres/fields/#django.contrib.postgres.fields.JSONField
Ubuntu 14.04 repositories contain only 9.3 version. You can review this to upgrade your version.
Based on the Anonymous comment, I found the following to work:
from django.contrib.postgres import fields
class OldJSONField(fields.JSONField):
def db_type(self, connection):
return 'json'
class Stop(models.Model):
...
latest_query_data = OldJSONField(default=dict)
...
If you are getting this error and you have installed Postgres > 9.4 then I would check that you aren't connecting to an older version of Postgres that is also installed on your instance.
To confirm what you are connecting to from Django you can use psycopg2 from the shell:
import psycopg2
conn = psycopg2.connect("dbname=<your database> user=<your user> password=<your password>")
cur = conn.cursor()
cur.execute("SELECT Version();")
cur.fetchone()
Make sure the version here is > 9.4. If not you probably have a couple of versions installed and your service configuration is pointing at the other version.
With older versions of PostgreSQL for example "PostgreSQL9.2.x",
We can use an alternative as
from jsonfield import JSONField
instead of:
from django.contrib.postgres.fields import JSONField
for example:
from django.db import models
from jsonfield import JSONField
class MyModel(models.Model):
json = JSONField()
Can install as:
pip install jsonfield
Check this out:
Add support for PostgreSQL 9.2+'s native json type. #32
This solution is especially good for some limited edition versions. For example,
on VPS & Cpanel that supports postgresql9.2 by default
more details!, see"rpkilby-jsonfield"
So, it seems a bug on psycopg2 or django, I will post an issue on both repositories. This is how I've solved (at least, ProgrammingError) the problem.
Change JSONField to TextField.
Flush your database.
Beware! This operation will erase all the data but the structure in your database.
Remove all migrations folder in all of your apps.
Run python3 manage.py makemigrations && python3 manage.py migrate in all of your apps.
Run python manage.py makemigrations <appname> && python3 manage.py migrate <appname> for each app you have.
Use built-in json module to convert between str and dict.
However, remember, this solution requires so much effort if you want to filter a QuerySet of a model. I do not recommend it, but there was no other solution to get rid of this error and all I needed to do was to save data and represent it.
! This answer will be accepted as default if there will not occur any other better solution in 48 hours.
When running
python3 manage.py migrate
I was asked what the default value of 'id' should be and entered 1. I had read
https://docs.djangoproject.com/en/1.9/howto/writing-migrations/#migrations-that-add-unique-fields
but that was a bit too complicated for me so tried 1.
Now when I run
python3 manage.py migrate
I get the following error:
vagrant#vagrant-ubuntu-trusty-64:/vagrant/grader$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, core, contenttypes, auth, sessions
Running migrations:
Rendering model states... DONE
Applying core.0002_auto_20160103_1302...Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: multiple default values specified for column "id" of table "core_student"
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.4/dist-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.4/dist-packages/django/core/management/__init__.py", line 342, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.4/dist-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.4/dist-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.4/dist-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards
field,
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/base/schema.py", line 396, in add_field
self.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/base/schema.py", line 110, in execute
cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python3.4/dist-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "core_student"
How can I recover from this failed migration? I went into the psql command promt and typed
SELECT * FROM core_students
It returned 0 rows so I don'w know why I have a problem.
Shouldn't Django automatically make the 'id' field be unique numbers?
EDIT:
The id has been auto generated by the Django migration.
student model:
class Student(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
owner = models.ForeignKey('auth.User', related_name='students')
identity_number = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
I often run into a similar problem where a migration fails for whatever reason, and only part of it gets applied to the database.
In theory you should be able to go into the database and run queries to finish the migration, but knowing what exact queries to run and what parts of the migration haven't been run is difficult in my experience.
The most dependable way I've found to fix it is to fake the migration, then back up the model, comment it out in models.py, then make a migration to delete it, then fake that as well. Then I can go into the database, drop the table, and then make a new migration to recreate it the way I now want to be.
Here are the commands I run:
python manage.py migrate --fake [appname] #fake the failed migration
#comment out the model in models.py and back up the data
python manage.py makemigrations [appname]
python manage.py migrate --fake [appname] #fake the migration to delete
the table
python manage.py dbshell
#drop the table. Mysql would be: DROP TABLE [appname]_[modelname];
#exit dbshell
#Uncomment the model in models.py adding in whatever changes were originally wanted
python manage.py makemigrations [appname]
python manage.py migrate #assuming your model change is valid, this should work this time.
#reload your data into the table
No, it's not elegant, but it gets django migrations working again without having to guess how far django got through a migration before it failed.
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)...
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;
If you cannot change your model name, then you can fix this problem by reducing the length of the generated Permission.name by specifying verbose_name in the model Meta class (see here for more details):
class MyVeryLongModelNameThatIsBreakingMyMigration(models.Model):
class Meta:
verbose_name = 'my long model'
Update
There's an open (as of 2013) Django ticket to fix this:
#8162 (Increase Permission.name max_length)
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.
I also got error like this one using postgresql django 1.2, but the problem was not the length, but using ugettext_lazy for translating the names. ('can_purge', _("Can purge")) is evidently unacceptable, since the name is stored in the database as text