Repository: getsentry/sentry

Issue:
Migration fails towards 8.4 on MySQL
```
Running migrations for sentry: 
- Migrating forwards to 0247_migrate_file_blobs. 
> sentry:0246_auto__add_dsymsymbol__add_unique_dsymsymbol_object_address__add_dsymsd 
FATAL ERROR - The following SQL query failed: CREATE INDEX `sentry_dsymobject_39c06cbd` ON `sentry_dsymobject` (`object_path`); 
The error was: (1170, "BLOB/TEXT column 'object_path' used in key specification without a key length") 
! Error found during real run of migration! Aborting.

! Since you have a database that does not support running 
! schema-altering statements in transactions, we have had 
! to leave it in an interim state between migrations.

! You *might* be able to recover with: = DROP INDEX `sentry_dsymsdk_version_major_8d012290987c340` ON `sentry_dsymsdk` [] 
- no dry run output for delete_unique_column() due to dynamic DDL, sorry 
= DROP TABLE `sentry_dsymsymbol` CASCADE; [] 
= DROP TABLE `sentry_dsymsdk` CASCADE; [] 
= DROP TABLE `sentry_dsymobject` CASCADE; [] 
= DROP TABLE `sentry_dsymbundle` CASCADE; []

! The South developers regret this has happened, and would 
! like to gently persuade you to consider a slightly 
! easier-to-deal-with DBMS (one that supports DDL transactions) 
! NOTE: The error which caused the migration to fail is further up. 
Error in migration: sentry:0246_auto__add_dsymsymbol__add_unique_dsymsymbol_object_address__add_dsymsd 
Traceback (most recent call last): 
File "/opt/sentry/venv/bin/sentry", line 9, in <module> 
load_entry_point('sentry==8.4.0', 'console_scripts', 'sentry')() 
File "/opt/sentry/venv/lib/python2.7/site-packages/sentry/runner/__init__.py", line 151, in main 
cli(prog_name=get_prog(), obj={}, max_content_width=100) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/core.py", line 716, in __call__ 
return self.main(*args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/core.py", line 696, in main 
rv = self.invoke(ctx) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/core.py", line 1060, in invoke 
return _process_result(sub_ctx.command.invoke(sub_ctx)) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/core.py", line 889, in invoke 
return ctx.invoke(self.callback, **ctx.params) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/core.py", line 534, in invoke 
return callback(*args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func 
return f(get_current_context(), *args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/sentry/runner/decorators.py", line 26, in inner 
return ctx.invoke(f, *args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/core.py", line 534, in invoke 
return callback(*args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func 
return f(get_current_context(), *args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/sentry/runner/commands/upgrade.py", line 37, in upgrade 
verbosity=verbosity, 
File "/opt/sentry/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 159, in call_command 
return klass.execute(*args, **defaults) 
File "/opt/sentry/venv/lib/python2.7/site-packages/raven/contrib/django/management/__init__.py", line 41, in new_execute 
return original_func(self, *args, **kwargs) 
File "/opt/sentry/venv/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute 
output = self.handle(*args, **options) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/management/commands/migrate.py", line 111, in handle 
ignore_ghosts = ignore_ghosts, 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/migration/__init__.py", line 220, in migrate_app 
success = migrator.migrate_many(target, workplan, database) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/migration/migrators.py", line 256, in migrate_many 
result = migrator.__class__.migrate_many(migrator, target, migrations, database) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/migration/migrators.py", line 331, in migrate_many 
result = self.migrate(migration, database) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/migration/migrators.py", line 133, in migrate 
result = self.run(migration, database) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/migration/migrators.py", line 114, in run 
return self.run_migration(migration, database) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/migration/migrators.py", line 85, in run_migration 
south.db.db.execute_deferred_sql() 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/db/generic.py", line 318, in execute_deferred_sql 
self.execute(sql) 
File "/opt/sentry/venv/lib/python2.7/site-packages/south/db/generic.py", line 282, in execute
cursor.execute(sql, params) 
File "/opt/sentry/venv/lib/python2.7/site-packages/raven/contrib/django/client.py", line 110, in execute 
return real_execute(self, sql, params) 
File "/opt/sentry/venv/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute 
return self.cursor.execute(sql, params) 
File "/opt/sentry/venv/lib/python2.7/site-packages/django/db/utils.py", line 99, in __exit__ 
six.reraise(dj_exc_type, dj_exc_value, traceback) 
File "/opt/sentry/venv/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute 
return self.cursor.execute(sql, params) 
File "/opt/sentry/venv/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 124, in execute 
return self.cursor.execute(query, args) 
File "/opt/sentry/venv/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value) 
File "/opt/sentry/venv/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler 
raise errorclass, errorvalue 
django.db.utils.OperationalError: (1170, "BLOB/TEXT column 'object_path' used in key specification without a key length") 
```

We can't use a `TextField` with an index on it. MySQL doesn't allow this. It must be a `CharField`.

@getsentry/infrastructure @mitsuhiko 



Discussion:

Resolving patch:
diff --git a/src/sentry/migrations/0246_auto__add_dsymsymbol__add_unique_dsymsymbol_object_address__add_dsymsd.py b/src/sentry/migrations/0246_auto__add_dsymsymbol__add_unique_dsymsymbol_object_address__add_dsymsd.py
--- a/src/sentry/migrations/0246_auto__add_dsymsymbol__add_unique_dsymsymbol_object_address__add_dsymsd.py
+++ b/src/sentry/migrations/0246_auto__add_dsymsymbol__add_unique_dsymsymbol_object_address__add_dsymsd.py
@@ -3,6 +3,7 @@
 from south.db import db
 from south.v2 import SchemaMigration
 from django.db import models
+from sentry.utils.db import is_mysql
 
 
 class Migration(SchemaMigration):
@@ -39,11 +40,22 @@ def forwards(self, orm):
         db.create_table('sentry_dsymobject', (
             ('id', self.gf('sentry.db.models.fields.bounded.BoundedBigAutoField')(primary_key=True)),
             ('cpu_name', self.gf('django.db.models.fields.CharField')(max_length=40)),
-            ('object_path', self.gf('django.db.models.fields.TextField')(db_index=True)),
+            ('object_path', self.gf('django.db.models.fields.TextField')(db_index=not is_mysql())),
             ('uuid', self.gf('django.db.models.fields.CharField')(max_length=36, db_index=True)),
             ('vmaddr', self.gf('sentry.db.models.fields.bounded.BoundedBigIntegerField')(null=True)),
             ('vmsize', self.gf('sentry.db.models.fields.bounded.BoundedBigIntegerField')(null=True)),
         ))
+
+        # On MySQL we need to create the index here differently because
+        # the index must have a limit.  As we have the type already
+        # defined to text in the model earlier we just restrict the index
+        # to 255.  The hash matches what south would have created.
+        if is_mysql():
+            db.execute('''
+                create index sentry_dsymobject_39c06cbd
+                          on sentry_dsymobject (object_path(255))
+            ''')
+
         db.send_create_signal('sentry', ['DSymObject'])
 
         # Adding model 'DSymBundle'
@@ -627,4 +639,4 @@ def backwards(self, orm):
         }
     }
 
-    complete_apps = ['sentry']
\ No newline at end of file
+    complete_apps = ['sentry']
diff --git a/src/sentry/utils/pytest.py b/src/sentry/utils/pytest.py
--- a/src/sentry/utils/pytest.py
+++ b/src/sentry/utils/pytest.py
@@ -24,6 +24,8 @@ def pytest_configure(config):
                 'NAME': 'sentry',
                 'USER': 'root',
             })
+            # mysql requires running full migration all the time
+            settings.SOUTH_TESTS_MIGRATE = True
         elif test_db == 'postgres':
             settings.DATABASES['default'].update({
                 'ENGINE': 'sentry.db.postgres',


Test patch: