summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_14/mutable_fix.rst9
-rw-r--r--lib/sqlalchemy/ext/mutable.py10
2 files changed, 17 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_14/mutable_fix.rst b/doc/build/changelog/unreleased_14/mutable_fix.rst
new file mode 100644
index 000000000..2c96878b8
--- /dev/null
+++ b/doc/build/changelog/unreleased_14/mutable_fix.rst
@@ -0,0 +1,9 @@
+.. change::
+ :tags: bug, orm, regression
+ :tickets: 8133
+
+ Fixed regression caused by :ticket:`8133` where the pickle format for
+ mutable attributes was changed, without a fallback to recognize the old
+ format, causing in-place upgrades of SQLAlchemy to no longer be able to
+ read pickled data from previous versions. A check plus a fallback for the
+ old format is now in place.
diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py
index 934ac37a0..cbec06a31 100644
--- a/lib/sqlalchemy/ext/mutable.py
+++ b/lib/sqlalchemy/ext/mutable.py
@@ -502,8 +502,14 @@ class MutableBase(object):
def unpickle(state, state_dict):
if "ext.mutable.values" in state_dict:
- for val in state_dict["ext.mutable.values"][key]:
- val._parents[state] = key
+ collection = state_dict["ext.mutable.values"]
+ if isinstance(collection, list):
+ # legacy format
+ for val in collection:
+ val._parents[state] = key
+ else:
+ for val in state_dict["ext.mutable.values"][key]:
+ val._parents[state] = key
event.listen(parent_cls, "load", load, raw=True, propagate=True)
event.listen(