Skip to content

Commit 78cdac7

Browse files
committed
feedback
1 parent 67b9356 commit 78cdac7

File tree

1 file changed

+17
-23
lines changed

1 file changed

+17
-23
lines changed

sqlmesh/migrations/v0085_deterministic_repr.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@
33
and therefore this migration applies deterministic sorting to the keys of the dictionary.
44
"""
55

6-
import ast
76
import json
87
import typing as t
8+
from dataclasses import dataclass
99

1010
from sqlglot import exp
1111

1212
from sqlmesh.utils.migration import index_text_type, blob_text_type
1313

1414

15+
# Make sure `SqlValue` is defined so it can be used by `eval` call in the migration
16+
@dataclass
17+
class SqlValue:
18+
"""A SQL string representing a generated SQLGlot AST."""
19+
20+
sql: str
21+
22+
1523
def _deterministic_repr(obj: t.Any) -> str:
1624
"""
1725
This is a copy of the function from utils.metaprogramming
@@ -27,7 +35,10 @@ def _normalize_for_repr(o: t.Any) -> t.Any:
2735
return type(o)(normalized)
2836
return o
2937

30-
return repr(_normalize_for_repr(obj))
38+
try:
39+
return repr(_normalize_for_repr(obj))
40+
except Exception:
41+
return repr(obj)
3142

3243

3344
def migrate(state_sync, **kwargs): # type: ignore
@@ -75,33 +86,16 @@ def migrate(state_sync, **kwargs): # type: ignore
7586
old_payload = executable["payload"]
7687
try:
7788
# Try to parse the old payload and re-serialize it deterministically
78-
parsed_value = ast.literal_eval(old_payload)
89+
parsed_value = eval(old_payload)
7990
new_payload = _deterministic_repr(parsed_value)
8091

8192
# Only update if the representation changed
8293
if old_payload != new_payload:
8394
executable["payload"] = new_payload
8495
migration_needed = True
85-
except (ValueError, SyntaxError):
86-
# Special handling for dictionaries containing SqlValue objects
87-
# These can't be parsed by ast.literal_eval but we can still make them deterministic
88-
if old_payload.startswith("{") and "SqlValue(" in old_payload:
89-
try:
90-
# Use eval in a safe context to parse SqlValue objects
91-
# This is safe because we're only running this on our own serialized data
92-
from sqlmesh.utils.metaprogramming import SqlValue
93-
94-
safe_globals = {"SqlValue": SqlValue}
95-
parsed_value = eval(old_payload, safe_globals, {})
96-
new_payload = _deterministic_repr(parsed_value)
97-
98-
# Only update if the representation changed
99-
if old_payload != new_payload:
100-
executable["payload"] = new_payload
101-
migration_needed = True
102-
except (ValueError, SyntaxError, NameError):
103-
# If we still can't parse it, leave it as-is
104-
pass
96+
except Exception:
97+
# If we still can't eval it, leave it as-is
98+
pass
10599

106100
new_snapshots.append(
107101
{

0 commit comments

Comments
 (0)