Opened 9 years ago
Closed 8 years ago
#25192 closed Bug (fixed)
Can't Squash Migration that uses migrations.RunPython.noop in Python 2
Reported by: | James Pulec | Owned by: | Shai Berger |
---|---|---|---|
Component: | Migrations | Version: | 1.8 |
Severity: | Normal | Keywords: | py2 |
Cc: | Shai Berger | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When trying to squash a set of migrations, if one of them uses migrations.RunPython.noop for a backwards or forward operation, a ValueError is raised due to an attempt to serialize an unbound method. Not sure if there should be a special check for that operation when attempting to run squashmigrations with Python2.
Traceback:
Traceback (most recent call last): File "manage.py", line 17, in <module> execute_from_command_line(sys.argv) File "/var/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line utility.execute() File "/var/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/var/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 393, in run_from_argv self.execute(*args, **cmd_options) File "/var/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute output = self.handle(*args, **options) File "/var/venv/local/lib/python2.7/site-packages/django/core/management/commands/squashmigrations.py", line 141, in handle fh.write(writer.as_string()) File "/var/venv/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 166, in as_string operation_string, operation_imports = OperationWriter(operation).serialize() File "/var/venv/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 124, in serialize _write(arg_name, arg_value) File "/var/venv/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 87, in _write arg_string, arg_imports = MigrationWriter.serialize(_arg_value) File "/var/venv/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 435, in serialize % (value.__name__, module_name, get_docs_version())) ValueError: Could not find function noop in django.db.migrations.operations.special. Please note that due to Python 2 limitations, you cannot serialize unbound method functions (e.g. a method declared and used in the same class body). Please move the function into the main module body to use migrations.
Change History (9)
comment:1 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 9 years ago
Keywords: | py2 added |
---|---|
Summary: | Can't Squash Migration that uses migrations.RunPython.noop in Python2 → Can't Squash Migration that uses migrations.RunPython.noop in Python 2 |
comment:3 by , 8 years ago
comment:4 by , 8 years ago
Cc: | added |
---|
I found a funny workaround: In my project, I added this squashmigrations
command (that is, a file management/commands/squashmigrations.py
in one of my projects' apps):
""" A squashmigrations command which does some monkeypatching on the RunPython operation to allow squashing migrations which use RunPython.noop, even on Python 2 """ from django.core.management.commands.squashmigrations import Command as DjangoCommand from django.db.migrations import RunPython # A staticmethod decorator is needed (out of a class!) because we are going to # monkeypatch this function into a class and it will be introspected by code that # will think it is an unbound instance method without the decorator. @staticmethod def noop(apps, schema_editor): return None class Command(DjangoCommand): def handle(self, **options): # Monkeypatch RunPython.noop = noop # Invoke original return super(Command, self).handle(**options)
Note the oddity of the @staticmethod
decorator on a function that isn't in a class.
I suppose we could use the same idea in fixing the bug in Django as well...
comment:5 by , 8 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Closing due to the end of Python 2 support in master in a couple weeks.
comment:6 by , 8 years ago
Resolution: | wontfix |
---|---|
Status: | closed → new |
comment:8 by , 8 years ago
Has patch: | set |
---|
I was hitting the same issue (when squashing migrations) and learned that you can simply add a global function to the migration script that does nothing (or copy from the existing noop) and refer to that from the RunPython function.
Paul