#24278 closed Bug (fixed)
squashmigrations throws ValueError: need more than 1 value to unpack
| Reported by: | Piotr Maliński | Owned by: | Marten Kenbeek |
|---|---|---|---|
| Component: | Migrations | Version: | 1.8 |
| Severity: | Normal | Keywords: | |
| Cc: | Markus Holtermann, michaelvantellingen@… | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
When squashing several migrations I got an exception during squashmigrations:
Traceback (most recent call last):
File "/env/bin/django-admin.py", line 5, in <module>
management.execute_from_command_line()
File "/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/env/lib/python3.4/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/env/lib/python3.4/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/env/lib/python3.4/site-packages/django/core/management/commands/squashmigrations.py", line 122, in handle
fh.write(writer.as_string())
File "/env/lib/python3.4/site-packages/django/db/migrations/writer.py", line 130, in as_string
operation_string, operation_imports = OperationWriter(operation).serialize()
File "/env/lib/python3.4/site-packages/django/db/migrations/writer.py", line 87, in serialize
arg_string, arg_imports = MigrationWriter.serialize(arg_value)
File "/env/lib/python3.4/site-packages/django/db/migrations/writer.py", line 260, in serialize
item_string, item_imports = cls.serialize(item)
File "/env/lib/python3.4/site-packages/django/db/migrations/writer.py", line 327, in serialize
return cls.serialize_deconstructed(*value.deconstruct())
File "/env/lib/python3.4/site-packages/django/db/migrations/writer.py", line 223, in serialize_deconstructed
module, name = path.rsplit(".", 1)
ValueError: need more than 1 value to unpack
The "path" variable got a value of "RenameField" instead of django.something.someField. I found one "migrations.RenameField" in the migrations set and after removing it (and "migrations.AlterField" which also caused such exception) the squash passed.
The migration (operations) with those fields looks like so:
operations = [
migrations.SeparateDatabaseAndState(state_operations=[
migrations.RenameField(
model_name='somemodel',
old_name='some_old_name',
new_name='new_name',
),
migrations.AlterField(
model_name='somemodel',
name='new_name',
field=models.BooleanField(db_column='some_old_name', default=False),
preserve_default=True,
),
]),
]
Change History (13)
comment:1 by , 11 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 11 years ago
Failing test case: Operations don't implement __eq__, so this is kinda useless.
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index 38065fb..4130e32 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -346,6 +346,18 @@ class WriterTests(TestCase):
self.assertSerializedEqual(FoodManager('a', 'b'))
self.assertSerializedEqual(FoodManager('x', 'y', c=3, d=4))
+ def test_serialize_operation(self):
+ """
+ Tests serializing an operation with MigrationWriter serialize. This happens when
+ serializing an operation within an operation, e.g. with SeparateDatabaseAndState.
+ """
+ operation = migrations.RenameField(
+ model_name="SomeModel",
+ old_name="old_name",
+ new_name="new_name",
+ )
+ self.assertSerializedEqual(operation)
+
def test_simple_migration(self):
"""
Tests serializing a simple migration.
comment:3 by , 11 years ago
| Has patch: | set |
|---|
PR: https://github.com/django/django/pull/4075
MigrationsWriter._serialize_path() now checks if there is a dot in the path, and if there isn't, assumes it is a class in django.db.migrations. As this module is always imported in generated migrations, I changed the imports to an empty dict and the name to migrations.<ClassName>.
This bug was caused by the fact that Operation.deconstruct() returns the class name as the first value instead of the full import path.
follow-up: 5 comment:4 by , 11 years ago
| Cc: | added |
|---|---|
| Patch needs improvement: | set |
I don't think this is the way to go. I'd prefer to find a way to use the django.db.migrations.writer.OperationWriter instead. This would also take care of indenting the respective output.
comment:5 by , 11 years ago
Replying to MarkusH:
I don't think this is the way to go. I'd prefer to find a way to use the
django.db.migrations.writer.OperationWriterinstead. This would also take care of indenting the respective output.
Yes, that indeed seems to be a better approach. I've pushed a new patch that uses the OperationWriter instead. (PR)
I think I'm gonna try to refactor this so that the isinstance(value, Operation) check is moved to MigrationWriter.serialize(). This would leave the _write function in OperationWriter.serialize() as a more general function, while MigrationWriter.serialize() handles the value-specific serialization. _write would still need to be able to handle multi-line values, but this also opens up the possibility for other objects to serialize into a multi-line string.
comment:6 by , 11 years ago
| Patch needs improvement: | unset |
|---|
comment:8 by , 11 years ago
| Cc: | added |
|---|
comment:9 by , 11 years ago
| Patch needs improvement: | unset |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
| Version: | 1.7 → 1.8 |
Confirmed, working on this now.