I recently switched from django-social-auth to python-social-auth, but it has clearly damage my migrations system. any time I try to migrate changes I got this one :
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 161, in handle
executor.migrate(targets, plan, fake=options.get("fake", False))
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/migrations/executor.py", line 68, in migrate
self.apply_migration(migration, fake=fake)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/migrations/executor.py", line 102, in apply_migration
migration.apply(project_state, schema_editor)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/migrations/migration.py", line 108, in apply
operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/migrations/operations/fields.py", line 139, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/schema.py", line 457, in alter_field
self._alter_field(model, old_field, new_field, old_type, new_type, old_db_params, new_db_params, strict)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/schema.py", line 603, in _alter_field
params,
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/schema.py", line 103, in execute
cursor.execute(sql, params)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "social_auth_code" does not exist
The problem being that it only happens in the production version of my app and that for some other reasons, I had to delete my migrations file in the past. Doesn't make it easy to investigate. Anyway, it perfectly work now with my development app but I can't figure out what can be the problem in production, I tried all the "faking migrations" tricks in the world and nothing seems to work.
the only place in the web were I can find such an error is there
but I never used South, so the first answer is not working for me.
Directly digging into the migrations table and sending raw SQL instructions could be the solution but since it is in my production version, I don't feel confortable with tinkering the db ( I got thousands of registered users, there data and all..). In short, I'm in deep sh*t :). Also, I don't know which command to use to directly access the migration table in the db...
Any solution that keeps my data safe is more than welcome :))
When migrating to python_social_auth I got the same error.
This is useful for Django 1.8.
Maybe my solution will help you:
Fake migrate initial of python_social_auth
python manage.py migrate default 0001 --fake
Create yourself migration for initial psa and put it to /your_project/your_app/migrations/0009_migrate_to_psa.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import social.apps.django_app.default.fields
from django.conf import settings
import social.storage.django_orm
from social.utils import setting_name
user_model = getattr(settings, setting_name('USER_MODEL'), None) or \
getattr(settings, 'AUTH_USER_MODEL', None) or \
'auth.User'
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(user_model),
('your_app', '0008_last_migration_in_your_app'),
('default', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Code',
fields=[
('id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True)),
('email', models.EmailField(max_length=75)),
('code', models.CharField(max_length=32, db_index=True)),
('verified', models.BooleanField(default=False)),
],
options={
'db_table': 'social_auth_code',
},
bases=(models.Model, social.storage.django_orm.DjangoCodeMixin),
),
migrations.AlterUniqueTogether(
name='code',
unique_together=set([('email', 'code')]),
),
]
Notice the dependencies:
dependencies = [
migrations.swappable_dependency(user_model),
('your_app', '0008_last_migration_in_your_app'),
('default', '0001_initial'),
]
Migrate your project
python manage.py migrate your_app
And migrate all
python manage.py migrate
UPDATE:
Unfortunately, this method requires a model Code in the file models.py your application. Otherwise the table will be deleted from the database when the next operation makemigrations.
/your_project/your_app/models.py:
from social.storage.django_orm import DjangoCodeMixin
class Code(models.Model, DjangoCodeMixin):
email = models.EmailField(max_length=254)
code = models.CharField(max_length=32, db_index=True)
verified = models.BooleanField(default=False)
class Meta:
db_table = 'social_auth_code'
unique_together = ('email', 'code')
I tried to run the solution before and had a bit of difficulties with the dependency.
I ended up just prepending1 the following lines to the Migration.operations list in migration 0007_code_timestamp (exactly as the original first answer suggested)
migrations.CreateModel(
name='Code',
fields=[
('id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True)),
('email', models.EmailField(max_length=75)),
('code', models.CharField(max_length=32, db_index=True)),
('verified', models.BooleanField(default=False)),
],
options={
'db_table': 'social_auth_code',
},
bases=(models.Model, social_django.storage.DjangoCodeMixin),
),
migrations.AlterUniqueTogether(
name='code',
unique_together=set([('email', 'code')]),
),
And make sure to import social_django at the top.
That solved it for me, it was easier than creating a new migration and dealing with the dependency clarification.
Related
I hope you're all well :) Could you please help me. I'm a beginner. I'm launching a new website with python and I choose wagtail for the CMS. I'd like to change the model of each blog_page in order to have more information on it. But I'm running into some issues :(
Everything was working with this code (blog/models.py) :
from django.db import models
from django import forms
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from wagtail.core.models import Page, Orderable
from wagtail.core.fields import RichTextField, StreamField
from wagtail.core import blocks
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel, MultiFieldPanel, TabbedInterface, ObjectList, StreamFieldPanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.images.blocks import ImageChooserBlock
from wagtail.search import index
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from wagtail.snippets.models import register_snippet
class BlogIndexPage(Page):
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
class BlogPageTag(TaggedItemBase):
content_object = ParentalKey(
'BlogPage',
related_name='tagged_items',
on_delete=models.CASCADE
)
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
recette = RichTextField(blank=True)
aliment = RichTextField(blank=True)
forcealiment = RichTextField(blank=True)
tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
categories = ParentalManyToManyField('blog.BlogCategory', blank=True)
def main_image(self):
gallery_item = self.gallery_images.first()
if gallery_item:
return gallery_item.image
else:
return None
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
index.SearchField('recette'),
index.SearchField('aliment'),
index.SearchField('forcealiment'),
]
content_panels = Page.content_panels + [
MultiFieldPanel([
FieldPanel('date'),
FieldPanel('tags'),
FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
], heading="Blog information"),
FieldPanel('intro'),
FieldPanel('body'),
FieldPanel('recette'),
FieldPanel('aliment'),
FieldPanel('forcealiment'),
InlinePanel('gallery_images', label="Gallery images"),
]
class BlogPageGalleryImage(Orderable):
page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name='gallery_images')
image = models.ForeignKey(
'wagtailimages.Image', on_delete=models.CASCADE, related_name='+'
)
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption'),
]
class BlogTagIndexPage(Page):
def get_context(self, request):
# Filter by tag
tag = request.GET.get('tag')
blogpages = BlogPage.objects.filter(tags__name=tag)
# Update template context
context = super().get_context(request)
context['blogpages'] = blogpages
return context
#register_snippet
class BlogCategory(models.Model):
name = models.CharField(max_length=255)
icon = models.ForeignKey(
'wagtailimages.Image', null=True, blank=True,
on_delete=models.SET_NULL, related_name='+'
)
panels = [
FieldPanel('name'),
ImageChooserPanel('icon'),
]
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'blog categories'
But when I try to add a new field 'cooker' like
cooker = models.CharField(max_length=250)
First stel is okay :
(monProjetWagtail:3.7)[dulo0814#louisiane monProjetWagtail]$ python manage.py makemigrations
Migrations for 'blog':
blog/migrations/0018_auto_20200522_1106.py
- Remove field autobio from blogpage
- Add field cooker to blogpage
Second step is not okay :(
(monProjetWagtail:3.7)[dulo0814#louisiane monProjetWagtail]$ python manage.py migrate
System check identified some issues:
WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://docs.djangoproject.com/en/3.0/ref/databases/#mysql-sql-mode
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, home, sessions, taggit, wagtailadmin, wagtailcore, wagtaildocs, wagtailembeds, wagtailforms, wagtailimages, wagtailredirects, wagtailsearch, wagtailusers
Running migrations:
Applying blog.0013_blogpage_autorpost...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 233, in handle
fake_initial=fake_initial,
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/migrations/executor.py", line 117, inmigrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/migrations/executor.py", line 147, in_migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/migrations/executor.py", line 245, inapply_migration
state = migration.apply(state, schema_editor)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/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 "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/migrations/operations/fields.py", line 112, in database_forwards
field,
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/backends/mysql/schema.py", line 80, in add_field
super().add_field(model, field)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 450, in add_field
definition, params = self.column_sql(model, field, include_default=True)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 223, in column_sql
default_value = self.effective_default(field)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 303, in effective_default
return field.get_db_prep_save(self._effective_default(field), self.connection)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 821,in get_db_prep_save
return self.get_db_prep_value(value, connection=connection, prepared=False)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 816,in get_db_prep_value
value = self.get_prep_value(value)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/wagtail/core/fields.py", line 111, in get_prep_value
return json.dumps(self.stream_block.get_prep_value(value), cls=DjangoJSONEncoder)
File "/home/dulo0814/virtualenv/monProjetWagtail/3.7/lib/python3.7/site-packages/wagtail/core/blocks/stream_block.py", line 260,in get_prep_value
return value.get_prep_value()
AttributeError: 'datetime.datetime' object has no attribute 'get_prep_value'
(monProjetWagtail:3.7)[dulo0814#louisiane monProjetWagtail]$
Can someone help me please :)?
Ps: I'm french
The error message shows that the error is on the migration 0013_blogpage_autorpost, not the 0018_auto_20200522_1106 migration you just created. Presumably you weren't running ./manage.py migrate after every makemigrations step (or you would have seen this error earlier).
The error is referring to a StreamField - it looks like you had a datetime object where there should have been a block. As there aren't any StreamFields in your models now, I guess this is a field that you added and subsequently removed (but it's still part of the migration history). My recommendation would be to delete all of the migration files in blog/migrations numbered 0013 and above, and then re-run ./manage.py makemigrations so that you have a new migration sequence without that error. (Normally, deleting migrations isn't a good idea, as it means that your database might end up in a state that doesn't match the code - but in this case I believe it should be safe, as the migrations from 0013 onward haven't been run yet.)
I have problems understanding how django's model fields work. What I want to achieve is something like a PriceField (DecimalField), that dynamically creates/injects another model field, let's say a currency (CharField) field.
I have read an interesing blog posts about this topic at https://blog.elsdoerfer.name/2008/01/08/fuzzydates-or-one-django-model-field-multiple-database-columns/. I think (and hope) that I've understood the core messages of the articles. But as most of them are a little bit outdated, I don't know if they are still valid for current django versions and my below code.
I use Django 1.11.4, Python 3.6.2, and a clean app created with ./manage.py startapp testing. The code in models.py:
from django.db import models
from django.db.models import signals
_currency_field_name = lambda name: '{}_extension'.format(name)
class PriceField(models.DecimalField):
def contribute_to_class(self, cls, name):
# add the extra currency field (CharField) to the class
if not cls._meta.abstract:
currency_field = models.CharField(
max_length=3,
editable=False,
null=True,
blank=True
)
cls.add_to_class(_currency_field_name(name), currency_field)
# add the original price field (DecimalField) to the class
super().contribute_to_class(cls, name)
# TODO: set the descriptor
# setattr(cls, self.name, FooDescriptor(self))
class FooModel(models.Model):
price = PriceField('agrhhhhh', decimal_places=3, max_digits=10, blank=True, null=True)
The problems come if I try to create migrations for that models. If executing python manage.py makemigrations following message is shown:
Migrations for 'testing':
testing/migrations/0001_initial.py
- Create model FooModel
Migration file 0001_initial.py has the following content:
# Generated by Django 1.11.4 on 2017-09-11 18:02
from __future__ import unicode_literals
from django.db import migrations, models
import testing.models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='FooModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('price', testing.models.PriceField(blank=True, decimal_places=3, max_digits=10, null=True, verbose_name='agrhhhhh')),
('price_extension', models.CharField(blank=True, editable=False, max_length=3, null=True)),
],
),
]
For me this looks OK so far. But if I then execute ./manage.py migrate testing, django shouts:
Operations to perform:
Apply all migrations: testing
Running migrations:
Applying testing.0001_initial...Traceback (most recent call last):
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/utils.py", line 63, in execute
return self.cursor.execute(sql)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 326, in execute
return Database.Cursor.execute(self, query)
sqlite3.OperationalError: duplicate column name: price_extension
Why does it error out on a duplicate column name: price_extension, when there is only one such field defined in the migrations file? Where does this duplicate field come from and is there a fix for this situation? Thanks!
Edit 1
This exception not only happens with an already existing database but also when I start with an empty database from scratch (deleting SQLite file). After the migrate command failed this is the structure of the DB:
./manage.py dbshell
sqlite> .tables
django_migrations
sqlite> .schema
CREATE TABLE "django_migrations" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "app" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "applied" datetime NOT NULL);
sqlite> select * from django_migrations;
sqlite>
And full stacktrace:
./manage.py migrate testing
Operations to perform:
Apply all migrations: testing
Running migrations:
Applying testing.0001_initial...Traceback (most recent call last):
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/utils.py", line 63, in execute
return self.cursor.execute(sql)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 326, in execute
return Database.Cursor.execute(self, query)
sqlite3.OperationalError: duplicate column name: price_extension
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "./manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
utility.execute()
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/core/management/__init__.py", line 355, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
fake_initial=fake_initial,
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/migrations/operations/models.py", line 97, in database_forwards
schema_editor.create_model(model)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 303, in create_model
self.execute(sql, params or None)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 120, in execute
cursor.execute(sql, params)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/utils.py", line 80, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/cachalot/monkey_patch.py", line 113, in inner
out = original(cursor, sql, *args, **kwargs)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/utils.py", line 63, in execute
return self.cursor.execute(sql)
File "/usr/local/var/pyenv/versions/stockmanagement-3.6.2/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 326, in execute
return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: duplicate column name: price_extension
Edit 2
A git repository with the above code can be found under: https://github.com/hetsch/django_testing. This error happens also if one clones this repository (clean project without any DB), calls makemigrations and then migrate.
According to Django ticket #22555 https://code.djangoproject.com/ticket/22555, this method of adding fields is not officially supported. Nonetheless, I made it work with the following simple fix:
def contribute_to_class(self, cls, name):
# add the extra currency field (CharField) to the class
# and prevent adding another field instance if the
# field was allready attached.
if not cls._meta.abstract and not hasattr(cls, _currency_field_name(name)):
currency_field = models.CharField(
max_length=3,
editable=False,
null=True,
blank=True
)
cls.add_to_class(_currency_field_name(name), currency_field)
I am trying to add One-to-One keys into my Django app, but I always get that error when I try to "migrate" process (makemigrations works great).
Applying xyzapp.0007_personne_extended_foreign...Traceback (most recent call last):
File "manage.py", line 29, in <module>
execute_from_command_line(sys.argv)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute_from_command_line
utility.execute()
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 346, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 394, in run_from_argv
self.execute(*args, **cmd_options)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 445, in execute
output = self.handle(*args, **options)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 222, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 110, in migrate
self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 148, in apply_migration
state = migration.apply(state, schema_editor)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 91, in __exit__
self.execute(sql)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 111, in execute
cursor.execute(sql, params)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/utils.py", line 98, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/opt/xyz/env/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 124, in execute
return self.cursor.execute(query, args)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 226, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorvalue
django.db.utils.OperationalError: (1005, 'Can\'t create table `xyz`.`#sql-600_297` (errno: 150 "Foreign key constraint is incorrectly formed")')
That's what my models looks like :
class PersonVolunteer(models.Model):
person = models.OneToOneField(Person)
class Person(models.Model):
name = models.CharField(max_length=100)
And the migration process that cause the crash :
class Migration(migrations.Migration):
dependencies = [
('xyzapp', '0014_member_to_person'),
]
operations = [
migrations.CreateModel(
name='PersonVolunteer',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('personne', models.OneToOneField(to='xyzapp.Personne')),
],
),
]
However, all works correctly when I test it even after the migrate error. But if that error message appears during "migrate", that should not be something good happening. If there's no problem, it is possible to skip that last step which crash my migration ?
Can someone can say me why do I get that error message and how I can resolve it ?
Thank you very much and have a great day !
I have found a solution, may be not the cleaner, but god dammit it works, that's perfect for me.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cvmapp', '0006_person_extended'),
]
operations = [
migrations.AddField(
model_name='PersonVolunteer',
name='personne',
field=models.OneToOneField(related_name='info_volunteer', to='cvmapp.Person', db_constraint=False),
),
]
The trick was to add "db_constraint=False" as a parameter of the OneToOne field.
Please make sure all your MySQL tables are using the same storage engine (i.e. MyISM v. InnoDB). Especially tables that have ForeignKeys between them.
If you need more information about MySQL storage engines and how to know which one(s) are you using you will need to read the MySQL documentation, although the MySQL notes in our database docs also have some introductory information.
I suspect you had tables created with the MyISAM storage engine (the default for MySQL < 5.5) and since MySQL 5.5 defaults to InnoDB and you created new tables since then, you ended with a mix
You can change the table storage engine from phpMyadmin. Click on your teble name, go to the 'operations' tab, and change in the "Table Operation" box. Convert all or your storage engine to the same.
First thing to do should be checking table's storage engines. However, in my case storage engines were same (both INNODB). My issue was unmatched collation of tables. After setting default char-set of the Database, my problem has been solved.
You can check table details with;
SHOW TABLE STATUS WHERE Name = "yyyyyyy";
Once you figure out your table's (that will be ForeignKey) collation, you can set your database default char-set as shown here like this:
ALTER DATABASE my_db COLLATE = 'latin1_swedish_ci';
Look at the output of the command SHOW ENGINE INNODB STATUS in MySql or MariaDB console client (mariadb link, mysql link). It`s more informative than error message.
For example, it showed me this message:
...
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2021-09-20 18:27:08 7faea3ad1700 Error in foreign key constraint of table `my_db`.`django_admin_log`:
Alter table `my_db`.`django_admin_log` with foreign key constraint failed. Referenced table `my_db`.`profiles_userprofile` not found in the data dictionary near ' FOREIGN KEY (`user_id`) REFERENCES `profiles_userprofile` (`id`)'.
...
It said to me that I forgot to create migrations.
I'm struggling to debug a vague error message in Django when executing any migration command:
Operations to perform:
Synchronize unmigrated apps: rest_framework_docs, staticfiles, django_coverage, django_extensions, storages, corsheaders, gis, templated_email, rest_framework, django_mptt_admin, opbeat.contrib.django, grappelli, permissions, django_nose, django_markdown, messages, common
Apply all migrations: contenttypes, auth, badges, reputation, geodata, comments, sites, users, votes, watchers, library, sessions, admin, oauth2_provider
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
No migrations to apply.
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 354, in execute_from_command_line
utility.execute()
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 346, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/base.py", line 394, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/base.py", line 445, in execute
output = self.handle(*args, **options)
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 205, in handle
executor.loader.project_state(),
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 353, in project_state
return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps))
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/db/migrations/graph.py", line 231, in make_state
project_state = self.nodes[node].mutate_state(project_state, preserve=False)
File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/db/migrations/migration.py", line 83, in mutate_state
operation.state_forwards(self.app_label, new_state)
File "/Users/user/Documents/workspace/user-api/env/lib/python3.4/site-packages/django/db/migrations/operations/models.py", line 52, in state_forwards
tuple(self.bases),
TypeError: 'ModelBase' object is not iterable
I've tracked the problem down to one of my apps, removing it clears the error. However, the error above does not help me understand the issue. Runserver works fine with no errors output.
The error is being generated from this line in Django: https://github.com/django/django/blob/master/django/db/migrations/operations/models.py#L83
What does this error relate to? The app itself does not generate any errors and runs fine, the app which gives this error is reputation.
Environment:
pillow==3.2.0
Django==1.8.7
psycopg2
Sphinx==1.2.3
django-mptt==0.7.2
sphinx_rtd_theme==0.1.6
django_extensions==1.3.3
django-mptt-admin==0.2.1
django-debug-toolbar==1.4
djangorestframework==3.3.3
django-oauth-toolkit==0.8.1
rest_condition==1.0.1
gevent==1.1rc3
gunicorn==19.3.0
django-cors-headers==1.1.0
django-simple-email-confirmation==0.12
itsdangerous==0.24
django-grappelli==2.7.1
numpy==1.11.0
reputation migrations:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
]
operations = [
migrations.CreateModel(
name='Reputation',
fields=[
('created', django_extensions.db.fields.CreationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='modified')),
('id', models.UUIDField(primary_key=True, unique=True,
('reputation', models.PositiveIntegerField(default=0)),
('dimension', models.CharField(max_length=2, blank=True, null=True)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='reputation_set')),
],
options={
'verbose_name': 'Reputation',
},
),
migrations.CreateModel(
name='ReputationAction',
fields=[
('created', django_extensions.db.fields.CreationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='modified')),
('id', models.UUIDField(primary_key=True, unique=True,
('action_type', models.CharField(max_length=10, blank=True, null=True)),
('value', models.IntegerField(default=0)),
('capped', models.BooleanField(default=0)),
('object_id', models.UUIDField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
('originating_user', models.ForeignKey(related_name='originating_user', to=settings.AUTH_USER_MODEL, null=True)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='target_user')),
],
options={
'verbose_name': 'Reputation Action',
},
bases=(models.Model),
),
]
2:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('reputation', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='reputationaction',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='reputation_action'),
),
]
3
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
def dedupe_reputation_actions(apps, schema_editor):
Reputation = apps.get_model('reputation', 'Reputation')
qs = Reputation.objects.all().values('user', 'dimension')\
.annotate(total=models.Count('user'))\
.filter(total__gt=1)
for dupe in qs:
reps = list(Reputation.objects.filter(user=dupe['user'], dimension=dupe['dimension']))
for rep in reps[1:]:
rep.delete()
class Migration(migrations.Migration):
dependencies = [
('reputation', '0002_auto_20151117_1108'),
]
operations = [
migrations.RunPython(dedupe_reputation_actions)
]
4
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reputation', '0003_auto_20160302_1749'),
]
operations = [
migrations.AlterUniqueTogether(
name='reputation',
unique_together=set([('user', 'dimension')]),
),
]
In your first migration:
migrations.CreateModel(
name='ReputationAction',
...
bases=(models.Model),
),
You need to change bases=(models.Model), to bases=(models.Model,), (note the extra comma). This will make bases a tuple containing the base Model class, rather than just the model class.
I'm not sure how your migrations would get into this state. Did you change the migrations manually? You might want to upgrade Django to the latest 1.8.x version, maybe there was a bug that has since been fixed.
I created a model but after 'makemigrations' and 'syncdb' the table doesn't appear in the database.
This is the second model that I want to create and the first model was not a problem.
The command 'makemigrations' creates a .py file, but syncdb shows the message "No migrations to apply".
What am I doing wrong?
python manage.py makemigrations
Migrations for 'category':
0006_text.py:
- Create model text
root#BB:~/Documenten/BB$ python manage.py syncdb
Operations to perform:
Synchronize unmigrated apps: admin-tools, theming
Apply all migrations: admin, category, contenttypes, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Installing custom SQL...
Installing indexes...
Running migrations:
No migrations to apply.
My models
from django.db import models
# Create your models here.
class textitem(models.Model):
bb_txt_lang = models.CharField(max_length=3)
bb_txt_cat = models.CharField(max_length=30)
bb_txt_title = models.CharField(max_length=50)
bb_txt_body = models.TextField()
bb_txt_footer = models.TextField()
# bb_txt_date_from = models.DateField()
# bb_txt_date_until= models.DateField()
bb_txt_status = models.BooleanField(default = False)
def __str__(self):
return self.bb_txt_title
class forum(models.Model):
bb_for_title = models.CharField(max_length=50)
bb_for_body = models.TextField()
bb_for_footer = models.TextField()
# bb_for_date_from = models.DateField()
# bb_for_date_until= models.DateField()
def __str__(self):
return self.bb_for_title
class category(models.Model):
bb_cat_lang = models.CharField(max_length=3)
bb_cat_desc = models.CharField(max_length=50)
# bb_cat_image = models.ImageField()
bb_cat_text = models.TextField()
bb_cat_prod = models.BooleanField(default = False)
bb_cat_sub = models.ForeignKey('category', null=True, blank=True )
def __str__(self):
return self.bb_cat_desc
The error code
biidbox#BiidBox:~/Documenten/BiidBox$ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: admin_tools, theming
Apply all migrations: admin, category, contenttypes, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Installing custom SQL...
Installing indexes...
Running migrations:
Applying category.0002_auto_20141128_1502...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 160, in handle
executor.migrate(targets, plan, fake=options.get("fake", False))
File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 63, in migrate
self.apply_migration(migration, fake=fake)
File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 97, in apply_migration
migration.apply(project_state, schema_editor)
File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/migration.py", line 107, in apply
operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/operations/fields.py", line 84, in database_forwards
schema_editor.remove_field(from_model, from_model._meta.get_field_by_name(self.name)[0])
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/schema.py", line 439, in remove_field
self.execute(sql)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/schema.py", line 99, in execute
cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "category_forum" does not exist
if you're using Django 1.7, which I assume since you're using makemigrations then syncdb is deprecated... you should be using migrate
https://docs.djangoproject.com/en/1.7/topics/migrations/#the-commands
see also:
https://docs.djangoproject.com/en/1.7/releases/1.7/#schema-migrations
When you make a fresh app with a fresh database, you run the commands in following order:
1) python manage.py syncdb
This creates all the tables that will be used by django (eg :auth_group, auth_user) etc.
You won't see your app's tables, after this command, in the database.
Then you do:
2) python manage.py makemigrations
This will run the initial migration and will detect all your new models.It just detects the models.Doesn't create tables in the database
After that,run the following command
3) python manage.py migrate
This will create your tables.
After you have done this, you just need to use (2) and (3) for any changes to happen.The changes could be creating new models or editing the schema of existing models, etc.
So now, in your question, when you ran python manage.py makemigration ,it detected your new model "text"
Now just run python manage.py migrate for the changes to take effect(in this case, to create table).
Hope this helps