Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Altering a field constrained with unique_together results in error 42000 #73

Closed
RussBaz opened this issue Aug 6, 2016 · 4 comments
Closed

Comments

@RussBaz
Copy link

RussBaz commented Aug 6, 2016

I am trying to apply django-allauth (0.26.1) migrations and I am getting the following exception:

Executing manage.py migrate
Operations to perform:
  Apply all migrations: account, admin, auth, contenttypes, sessions, sites, socialaccount
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying account.0001_initial... OK
  Applying account.0002_email_max_length... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK
  Applying socialaccount.0001_initial... OK
  Applying socialaccount.0002_token_max_lengths...Traceback (most recent call last):
  File "D:\Projects\myproject\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "D:\Projects\myproject\env\lib\site-packages\sql_server\pyodbc\base.py", line 538, in execute
    return self.cursor.execute(sql, params)
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]The object 'socialaccount_socialaccount_provider_fc810c6e_uniq' is dependent on column 'uid'. (5074) (SQLExecDirectW)")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\Projects\myproject\src/manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "D:\Projects\myproject\env\lib\site-packages\django\core\management\__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "D:\Projects\myproject\env\lib\site-packages\django\core\management\__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\Projects\myproject\env\lib\site-packages\django\core\management\base.py", line 305, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\Projects\myproject\env\lib\site-packages\django\core\management\base.py", line 356, in execute
    output = self.handle(*args, **options)
  File "D:\Projects\myproject\env\lib\site-packages\django\core\management\commands\migrate.py", line 202, in handle
    targets, plan, fake=fake, fake_initial=fake_initial
  File "D:\Projects\myproject\env\lib\site-packages\django\db\migrations\executor.py", line 97, in migrate
    state = self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\migrations\executor.py", line 132, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\migrations\executor.py", line 237, in apply_migration
    state = migration.apply(state, schema_editor)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\migrations\migration.py", line 129, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\migrations\operations\fields.py", line 204, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\backends\base\schema.py", line 495, in alter_field
    old_db_params, new_db_params, strict)
  File "D:\Projects\myproject\env\lib\site-packages\sql_server\pyodbc\schema.py", line 244, in _alter_field
    params,
  File "D:\Projects\myproject\env\lib\site-packages\sql_server\pyodbc\schema.py", line 554, in execute
    cursor.execute(sql, params)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "D:\Projects\myproject\env\lib\site-packages\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "D:\Projects\myproject\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "D:\Projects\myproject\env\lib\site-packages\sql_server\pyodbc\base.py", line 538, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]The object 'socialaccount_socialaccount_provider_fc810c6e_uniq' is dependent on column 'uid'. (5074) (SQLExecDirectW)")
The Python REPL process has exited

And here is the misbehaving migration from django-allauth:
(D:\Projects\myproject\env\Lib\site-packages\allauth\socialaccount\migrations\0002_token_max_lengths.py)

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
from django.conf import settings


class Migration(migrations.Migration):

    dependencies = [
        ('socialaccount', '0001_initial'),
    ]

    operations = [
        migrations.AlterField(
            model_name='socialaccount',
            name='uid',
            field=models.CharField(max_length=getattr(settings, 'SOCIALACCOUNT_UID_MAX_LENGTH', 191), verbose_name='uid'),
        ),
        migrations.AlterField(
            model_name='socialapp',
            name='client_id',
            field=models.CharField(help_text='App ID, or consumer key', max_length=191, verbose_name='client id'),
        ),
        migrations.AlterField(
            model_name='socialapp',
            name='key',
            field=models.CharField(help_text='Key', max_length=191, verbose_name='key', blank=True),
        ),
        migrations.AlterField(
            model_name='socialapp',
            name='secret',
            field=models.CharField(help_text='API secret, client secret, or consumer secret', max_length=191, verbose_name='secret key'),
        ),
    ]

This is the initial migration which the failing one depends on:
(D:\Projects\myproject\env\Lib\site-packages\allauth\socialaccount\migrations\0001_initial.py)

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from django.conf import settings
import allauth.socialaccount.fields
from allauth.socialaccount.providers import registry


class Migration(migrations.Migration):

    dependencies = [
        ('sites', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='SocialAccount',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('provider', models.CharField(max_length=30, verbose_name='provider', choices=registry.as_choices())),
                ('uid', models.CharField(max_length=255, verbose_name='uid')),
                ('last_login', models.DateTimeField(auto_now=True, verbose_name='last login')),
                ('date_joined', models.DateTimeField(auto_now_add=True, verbose_name='date joined')),
                ('extra_data', allauth.socialaccount.fields.JSONField(default='{}', verbose_name='extra data')),
                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'verbose_name': 'social account',
                'verbose_name_plural': 'social accounts',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='SocialApp',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('provider', models.CharField(max_length=30, verbose_name='provider', choices=registry.as_choices())),
                ('name', models.CharField(max_length=40, verbose_name='name')),
                ('client_id', models.CharField(help_text='App ID, or consumer key', max_length=100, verbose_name='client id')),
                ('secret', models.CharField(help_text='API secret, client secret, or consumer secret', max_length=100, verbose_name='secret key')),
                ('key', models.CharField(help_text='Key', max_length=100, verbose_name='key', blank=True)),
                ('sites', models.ManyToManyField(to='sites.Site', blank=True)),
            ],
            options={
                'verbose_name': 'social application',
                'verbose_name_plural': 'social applications',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='SocialToken',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('token', models.TextField(help_text='"oauth_token" (OAuth1) or access token (OAuth2)', verbose_name='token')),
                ('token_secret', models.TextField(help_text='"oauth_token_secret" (OAuth1) or refresh token (OAuth2)', verbose_name='token secret', blank=True)),
                ('expires_at', models.DateTimeField(null=True, verbose_name='expires at', blank=True)),
                ('account', models.ForeignKey(to='socialaccount.SocialAccount')),
                ('app', models.ForeignKey(to='socialaccount.SocialApp')),
            ],
            options={
                'verbose_name': 'social application token',
                'verbose_name_plural': 'social application tokens',
            },
            bases=(models.Model,),
        ),
        migrations.AlterUniqueTogether(
            name='socialtoken',
            unique_together=set([('app', 'account')]),
        ),
        migrations.AlterUniqueTogether(
            name='socialaccount',
            unique_together=set([('provider', 'uid')]),
        ),
    ]

Also, I am using SQL Server 2016 Express with windows 10, Python 3.5.2 (64 bit) and Django 1.10.

Is this a bug of django-pyodbc-azure?

Thank you.

@RussBaz RussBaz changed the title Django-allauth migrations results in ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]The object 'socialaccount_socialaccount_provider_fc810c6e_uniq' is dependent on column 'uid'. (5074) (SQLExecDirectW)") Altering a field constrained with unique_together results in error 42000 Aug 12, 2016
@RussBaz
Copy link
Author

RussBaz commented Aug 12, 2016

I think I identified the root cause of the problem and updated the title accordingly. It looks like altering constrained with unique_together field raises an exception. Manual dropping of such constraint allows the migration process to continue. The schema.py already has a check for unique constraints but it seems it needs a unique_together constraint test too.

Thanks.

michiya added a commit that referenced this issue Aug 14, 2016
michiya added a commit that referenced this issue Aug 14, 2016
michiya added a commit that referenced this issue Aug 14, 2016
@michiya
Copy link
Owner

michiya commented Aug 14, 2016

@RussBaz Thank you for reporting! I've made the fix for the issue and pushed it to PyPI. Please let me know if you still have the same problem after upgrading django-pyodbc-azure to the latest one.

@RussBaz
Copy link
Author

RussBaz commented Aug 15, 2016

Awesome, I just checked it and it worked flawlessly. Thanks again!

@RussBaz RussBaz closed this as completed Aug 15, 2016
@hermanocabral
Copy link

hermanocabral commented Feb 21, 2017

@michiya

Just recently got this same error when trying to alter the length of field constrained with unique_together:

django.db.utils.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The object 'foo_firearm_manufacturer_1f9cee95_uniq' is dependent on column 'serial_number'. (5074) (SQLExecDirectW)")

My "fix" was to "remove" the unique constraint at the beginning of the migration and then recreate it at the end:

class Migration(migrations.Migration):

    dependencies = [
        ('foo', '0345_add_more_cowbell'),
    ]

    operations = [
        migrations.AlterUniqueTogether(
            name='firearm',
            unique_together=set([]),
        ),
        ...,
        migration code goes here,
        ...,
        migrations.AlterUniqueTogether(
            name='firearm',
            unique_together=set([('field1', 'field2', 'field3', ..., 'fieldN')]),
        ),
    ]

Using:

  • Django==1.9.12
  • django-pyodbc-azure==1.9.12.0
  • pyodbc==4.0.11
  • driver: ODBC Driver 13 for SQL Server
  • SQL LocalDB v12.0
  • Python 3.4.5 :: Continuum Analytics, Inc. (anaconda)

*The error is pretty much exactly the same as the OP's, so I just posted the final line to avoid a giant blob of the same text over and over again. I can provide more details if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants