Repository: translate/pootle

Issue:
Duplicate entry '0-89' for key 'pootleprofile_id
This is on LibreOffice deployment at this URL https://translations.documentfoundation.org/user/indrit.bsh/settings/

I'm not 100% sure what the user is doing.   But I suspect we want to make sure there is some sort of PootleProfile cleanup if we do indeed have such duplicates post migration.

``` pytb
Traceback (most recent call last):
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/newrelic-2.50.0.39/newrelic/api/web_transaction.py", line 711, in __iter__
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/newrelic-2.50.0.39/newrelic/api/web_transaction.py", line 1087, in __call__
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 187, in __call__
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/newrelic-2.50.0.39/newrelic/hooks/framework_django.py", line 499, in wrapper
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
File "/var/www/sites/translations.documentfoundation.org/src/pootle/core/views.py", line 68, in dispatch
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/utils/decorators.py", line 29, in _wrapper
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in bound_func
File "/var/www/sites/translations.documentfoundation.org/src/pootle/core/views.py", line 45, in dispatch
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/newrelic-2.50.0.39/newrelic/hooks/framework_django.py", line 872, in wrapper
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 230, in post
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 173, in post
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 149, in form_valid
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/forms/models.py", line 455, in save
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/forms/models.py", line 104, in save_instance
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/forms/models.py", line 100, in save_m2m
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 2298, in save_form_data
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1193, in __set__
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 924, in add
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1042, in _add_items
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 409, in bulk_create
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 938, in _batched_insert
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 921, in _insert
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 921, in execute_sql
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 129, in execute
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/newrelic-2.50.0.39/newrelic/hooks/database_dbapi2.py", line 22, in execute
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
File "/var/www/sites/translations.documentfoundation.org/env/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
```



Discussion:
Will need a better backtrace than that to figure this one out. It might be related to the previous migrations we ran which broke, no?

Closed by accident. Reopening this.

I think we fixed this a while back.

@jleclanche we didn't, got this email from @EmiXLabs

```
When my friend after registration and few suggestions tried to add
suggestion language to his profile (English-en) got this error.

Exception: (1062, "Duplicate entry '0-29' for key 'pootleprofile_id'")

If you need assistance, you may refer to this error as
8521a1004a714f29bd18874a3ec13743.
```

Suggestion language here would be alt-src language

The error occured on http://mozilla.locamotion.org/user/halil/settings/

``` pytb
Traceback (most recent call last):
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/newrelic-2.52.0.40/newrelic/api/web_transaction.py", line 711, in __iter__
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/newrelic-2.52.0.40/newrelic/api/web_transaction.py", line 1087, in __call__
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 187, in __call__
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/transaction.py", line 394, in inner
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/newrelic-2.52.0.40/newrelic/hooks/framework_django.py", line 499, in wrapper
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
  File "/var/www/sites/mozilla/src/pootle/core/views.py", line 68, in dispatch
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/utils/decorators.py", line 29, in _wrapper
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in bound_func
  File "/var/www/sites/mozilla/src/pootle/core/views.py", line 45, in dispatch
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/newrelic-2.52.0.40/newrelic/hooks/framework_django.py", line 872, in wrapper
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 230, in post
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 173, in post
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 149, in form_valid
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/forms/models.py", line 455, in save
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/forms/models.py", line 104, in save_instance
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/forms/models.py", line 100, in save_m2m
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 2298, in save_form_data
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1193, in __set__
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 924, in add
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1042, in _add_items
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 409, in bulk_create
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 938, in _batched_insert
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 921, in _insert
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 921, in execute_sql
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 129, in execute
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/newrelic-2.52.0.40/newrelic/hooks/database_dbapi2.py", line 22, in execute
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
  File "/var/www/sites/mozilla/env/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
```

Another instance [reported against LibreOffice](https://redmine.documentfoundation.org/issues/1406) which seems to confirm that this is when a user wants to add alt-src languages to their profile.

Found this during the on-going Mozilla localization hackathon. The bug has been verified by @guerojeff and @Saikeo (Lao team). 

Steps to reproduce the error. 
1. Go to user preferences. 
2. Add a new locale to 'Alternative Source Languages'
3. Hit save 


Resolving patch:
diff --git a/pootle/apps/accounts/migrations/0003_remove_pootleprofile_id.py b/pootle/apps/accounts/migrations/0003_remove_pootleprofile_id.py
new file mode 100644
--- /dev/null
+++ b/pootle/apps/accounts/migrations/0003_remove_pootleprofile_id.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def fix_accounts_alt_src_langs(apps, schema_editor):
+    """Remove pootleprofile_id column from accounts_user_alt_src_langs
+
+    After migration from 2.5.x the pootleprofile_id column is left on
+    the m2m table accounts_user_alt_src_langs causing uniqueness issues
+    (#3856). This migration removes the problem column on mysql.
+    """
+
+    cursor = schema_editor.connection.cursor()
+
+    # Check its mysql - should probs check its not too old.
+    if not hasattr(cursor.db, "mysql_version"):
+        return
+
+    # Get the db_name and table_name.
+    db_name = cursor.db.get_connection_params()['db']
+    table_name = (apps.get_model("accounts.User")
+                  ._meta.local_many_to_many[0].m2m_db_table())
+
+    # Check the problem column exists.
+    cursor.execute("SELECT COLUMN_NAME"
+                   " FROM INFORMATION_SCHEMA.COLUMNS"
+                   " WHERE TABLE_SCHEMA = '%s'"
+                   "   AND TABLE_NAME = '%s'"
+                   "   AND COLUMN_NAME = 'pootleprofile_id';"
+                   % (db_name, table_name))
+    if not cursor.fetchone():
+        return
+
+    # Get constraints for column.
+    cursor.execute("SELECT CONSTRAINT_NAME "
+                   "  FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE "
+                   "  WHERE TABLE_SCHEMA = '%s' "
+                   "    AND TABLE_NAME = '%s' "
+                   "    AND COLUMN_NAME = 'pootleprofile_id'"
+                   % (db_name, table_name))
+    uniq = None
+    fk = None
+    default = False
+    for constraint in cursor.fetchall():
+        if constraint[0].endswith("uniq"):
+            uniq = constraint[0]
+        elif constraint[0].startswith("pootleprofile_id_refs"):
+            fk = constraint[0]
+        elif constraint[0] == "pootleprofile_id":
+            default = True
+
+    # Removing uniq/fk has to happen in this order.
+    if uniq:
+        # Remove unique constraint.
+        cursor.execute("ALTER TABLE %s "
+                       "  DROP KEY %s"
+                       % (table_name, uniq))
+    if fk:
+        # Remove foreign key constraint.
+        cursor.execute("ALTER TABLE %s "
+                       "  DROP FOREIGN KEY %s"
+                       % (table_name, fk))
+
+    if default:
+        # Remove unique constraint from older migrated db.
+        cursor.execute("DROP INDEX pootleprofile_id"
+                       "   ON %s;" % (table_name))
+
+    # Remove column.
+    cursor.execute("ALTER TABLE %s "
+                   "  DROP COLUMN pootleprofile_id"
+                   % (table_name))
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('accounts', '0002_user_alt_src_langs'),
+    ]
+
+    operations = [
+        migrations.RunPython(fix_accounts_alt_src_langs),
+    ]


Test patch: