grantmcconnaughey / django-field-history

A Django app to track changes to model fields.
BSD 3-Clause "New" or "Revised" License
314 stars 33 forks source link

FieldHistory.object_id causes MySQL error during migration 0001 #16

Closed benglazer closed 7 years ago

benglazer commented 7 years ago

InnoDB indexes in MySQL can only be created for columns with a max length of 767 bytes (see the third bullet under Maximums and Minimums), so the TextField that FieldHistory.object_id currently uses causes migration 0001 to throw an exception. Example output:

Operations to perform:
  Apply all migrations: field_history
Running migrations:
  Rendering model states... DONE
  Applying field_history.0001_initial...Traceback (most recent call last):
  File "project/proj/manage.py", line 8, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute_from_command_line
    utility.execute()
  File "/usr/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 "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 394, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python2.7/site-packages/raven/contrib/django/management/__init__.py", line 41, in new_execute
    return original_func(self, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 445, in execute
    output = self.handle(*args, **options)
  File "/usr/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 "/usr/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 "/usr/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 148, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 91, in __exit__
    self.execute(sql)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 111, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/utils.py", line 98, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 124, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
django.db.utils.OperationalError: (1170, "BLOB/TEXT column 'object_id' used in key specification without a key length")

The obvious solution is to change FieldHistory.object_id to a fixed-length field, such as a CharField.

benglazer commented 7 years ago

Have written a proof-of-concept that uses TextField by default but allows a setting to override the field type (so current django-field-history users will be completely unaffected, but new users can use whatever object_id type they like). Will submit a pull request shortly.