annotate libervia/backend/memory/migration/versions/fe3a02cb4bec_convert_legacypickle_columns_to_json.py @ 4270:0d7bb4df2343

Reformatted code base using black.
author Goffi <goffi@goffi.org>
date Wed, 19 Jun 2024 18:44:57 +0200
parents 79a4870cfbdf
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 """convert LegacyPickle columns to JSON
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 Revision ID: fe3a02cb4bec
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 Revises: 610345f77e75
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 Create Date: 2024-02-22 14:55:59.993983
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 """
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4228
diff changeset
8
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 from alembic import op
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 import sqlalchemy as sa
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 import pickle
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 import json
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4228
diff changeset
13
4228
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
14 try:
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
15 from libervia.backend.plugins.plugin_xep_0373 import PublicKeyMetadata
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
16 except Exception:
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
17 PublicKeyMetadata = None
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
18 print(
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
19 "Warning: Can't import XEP-0373, its data won't be updated. It's probably not "
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
20 "used on this installation."
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
21 )
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
22 try:
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
23 from libervia.backend.plugins.plugin_xep_0384 import TrustMessageCacheEntry
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
24 except Exception:
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
25 TrustMessageCacheEntry = None
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
26 print(
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
27 "Warning: Can't import XEP-0384, its data won't be updated. It's probably not "
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
28 "used on this installation."
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
29 )
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
30
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 # revision identifiers, used by Alembic.
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 revision = "fe3a02cb4bec"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 down_revision = "610345f77e75"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 branch_labels = None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 depends_on = None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 def convert_pickle_to_json(value, table, primary_keys):
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 """Convert pickled data to JSON, handling potential errors."""
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 if value is None:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 return None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 try:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 # some values are converted to bytes with LegacyPickle
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 if isinstance(value, str):
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 value = value.encode()
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 try:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 deserialized = pickle.loads(value, encoding="utf-8")
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 except ModuleNotFoundError:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 deserialized = pickle.loads(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 value.replace(b"sat.plugins", b"libervia.backend.plugins"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 encoding="utf-8",
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 if (
4228
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
54 PublicKeyMetadata is not None
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
55 and table == "private_ind_bin"
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 and primary_keys[0] == "XEP-0373"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 and not primary_keys[1].startswith("/trust")
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 and isinstance(deserialized, set)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 and deserialized
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 and isinstance(next(iter(deserialized)), PublicKeyMetadata)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 ):
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 # XEP-0373 plugin was pickling an internal class, this can't be converted
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 # directly to JSON, so we do a special treatment with the add `to_dict` and
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 # `from_dict` methods.
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 deserialized = [pkm.to_dict() for pkm in deserialized]
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
66
4216
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
67 elif (
4228
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
68 TrustMessageCacheEntry is not None
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
69 and table == "private_ind_bin"
4216
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
70 and primary_keys[0] == "XEP-0384/TM"
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
71 and primary_keys[1] == "cache"
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
72 ):
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
73 # Same issue and solution as for XEP-0373
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
74 try:
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
75 deserialized = [tm.to_dict() for tm in deserialized]
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
76 except Exception as e:
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
77 print(
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
78 "Warning: Failed to convert Trust Management cache with value "
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
79 f" {deserialized!r}, using empty array instead: {e}"
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
80 )
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4228
diff changeset
81 deserialized = []
4216
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
82
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 ret = json.dumps(deserialized, ensure_ascii=False, default=str)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4228
diff changeset
84 if table == "history" and ret == "{}":
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 # For history, we can remove empty data, but for other tables it may be
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 # significant.
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 ret = None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 return ret
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 except Exception as e:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 print(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 f"Warning: Failed to convert pickle to JSON, using NULL instead. Error: {e}"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 return None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
94
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
95
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 def upgrade():
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 print(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 "This migration may take very long, please be patient and don't stop the process."
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 connection = op.get_bind()
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
101
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 tables_and_columns = [
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 ("history", "extra", "uid"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 ("private_gen_bin", "value", "namespace", "key"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 ("private_ind_bin", "value", "namespace", "key", "profile_id"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 ]
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
107
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 for table, column, *primary_keys in tables_and_columns:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 primary_key_clause = " AND ".join(f"{pk} = :{pk}" for pk in primary_keys)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 select_stmt = sa.text(f"SELECT {', '.join(primary_keys)}, {column} FROM {table}")
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 update_stmt = sa.text(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 f"UPDATE {table} SET {column} = :{column} WHERE {primary_key_clause}"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
114
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 result = connection.execute(select_stmt)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 for row in result:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 value = row[-1]
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 if value is None:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 continue
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 data = {pk: row[idx] for idx, pk in enumerate(primary_keys)}
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 data[column] = convert_pickle_to_json(value, table, row[:-1])
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 connection.execute(update_stmt.bindparams(**data))
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
123
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
124
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 def convert_json_to_pickle(value, table, primary_keys):
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 """Convert JSON data back to pickled data, handling potential errors."""
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 if value is None:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 return None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 try:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 deserialized = json.loads(value)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 # Check for the specific table and primary key conditions that require special
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 # handling
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 if (
4228
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
134 PublicKeyMetadata is not None
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
135 and table == "private_ind_bin"
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 and primary_keys[0] == "XEP-0373"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 and not primary_keys[1].startswith("/trust")
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 ):
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 # Convert list of dicts back to set of PublicKeyMetadata objects
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 if isinstance(deserialized, list):
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 deserialized = {PublicKeyMetadata.from_dict(d) for d in deserialized}
4216
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
142 elif (
4228
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
143 TrustMessageCacheEntry is not None
79a4870cfbdf migration: fix migration when XEP-0373 or XEP-0384 can't be imported:
Goffi <goffi@goffi.org>
parents: 4216
diff changeset
144 and table == "private_ind_bin"
4216
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
145 and primary_keys[0] == "XEP-0384/TM"
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
146 and primary_keys[1] == "cache"
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
147 ):
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
148 # Convert list of dicts back to set of TrustMessageCacheEntry objects
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
149 if isinstance(deserialized, list):
1a7a3e4b52a4 core (memory/migration):
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
150 deserialized = {TrustMessageCacheEntry.from_dict(d) for d in deserialized}
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 return pickle.dumps(deserialized, 0)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 except Exception as e:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 print(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 f"Warning: Failed to convert JSON to pickle, using NULL instead. Error: {e}"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 return None
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
157
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
158
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 def downgrade():
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 print(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 "Reverting JSON columns to LegacyPickle format. This may take a while, please be "
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 "patient."
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 connection = op.get_bind()
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
165
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 tables_and_columns = [
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 ("history", "extra", "uid"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 ("private_gen_bin", "value", "namespace", "key"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 ("private_ind_bin", "value", "namespace", "key", "profile_id"),
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 ]
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
171
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 for table, column, *primary_keys in tables_and_columns:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 primary_key_clause = " AND ".join(f"{pk} = :{pk}" for pk in primary_keys)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 select_stmt = sa.text(f"SELECT {', '.join(primary_keys)}, {column} FROM {table}")
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 update_stmt = sa.text(
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 f"UPDATE {table} SET {column} = :{column} WHERE {primary_key_clause}"
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 )
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
178
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 result = connection.execute(select_stmt)
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 for row in result:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 value = row[-1]
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 if value is None:
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 continue
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 data = {pk: row[idx] for idx, pk in enumerate(primary_keys)}
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 data[column] = convert_json_to_pickle(value, table, row[:-1])
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 connection.execute(update_stmt.bindparams(**data))