Skip to content

Commit ea7b377

Browse files
authored
Fix: Fix Windows faulthandler and seed path (#1162)
* fix window seed path and faulthandler * remove commented out code
1 parent aba8e0d commit ea7b377

7 files changed

Lines changed: 72 additions & 6 deletions

File tree

sqlmesh/cli/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ def cli(
7373

7474
# Enable threadumps.
7575
faulthandler.enable()
76-
faulthandler.register(signal.SIGUSR1.value)
76+
# Windows doesn't support register so we check for it here
77+
if hasattr(faulthandler, "register"):
78+
faulthandler.register(signal.SIGUSR1.value)
7779
enable_logging(level=logging.DEBUG)
7880
elif ignore_warnings:
7981
logging.getLogger().setLevel(logging.ERROR)

sqlmesh/core/dialect.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,11 @@ def _parse_props(self: Parser) -> t.Optional[exp.Expression]:
267267
)
268268
else:
269269
value = self._parse_bracket(self._parse_field(any_token=True))
270-
271-
return self.expression(exp.Property, this=key.name.lower(), value=value)
270+
name = key.name.lower()
271+
if name == "path" and value:
272+
# Make sure if we get a windows path that it is converted to posix
273+
value = exp.Literal.string(value.this.replace("\\", "/"))
274+
return self.expression(exp.Property, this=name, value=value)
272275

273276

274277
def _create_parser(parser_type: t.Type[exp.Expression], table_keys: t.List[str]) -> t.Callable:

sqlmesh/core/model/seed.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ def _get_df(self) -> pd.DataFrame:
5353

5454

5555
def create_seed(path: str | Path) -> Seed:
56-
with open(path, "r") as fd:
56+
with open(Path(path), "r") as fd:
5757
return Seed(content=fd.read())

sqlmesh/dbt/seed.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ def to_sqlmesh(self, context: DbtContext) -> Model:
2222
"""Converts the dbt seed into a SQLMesh model."""
2323
return create_seed_model(
2424
self.sql_name,
25-
SeedKind(path=self.path.absolute()),
25+
SeedKind(path=self.path.absolute().as_posix()),
2626
**self.sqlmesh_model_kwargs(context),
2727
)

sqlmesh/integrations/github/cicd/controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def from_obj(cls, obj: t.Dict[str, t.Any]) -> GithubEvent:
151151

152152
@classmethod
153153
def from_path(cls, path: t.Union[str, pathlib.Path]) -> GithubEvent:
154-
with open(path) as f:
154+
with open(pathlib.Path(path)) as f:
155155
return cls.from_obj(json.load(f))
156156

157157
@classmethod
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""Fix seed paths that have a Windows forward slash in them."""
2+
import json
3+
4+
import pandas as pd
5+
from sqlglot import exp
6+
7+
8+
def migrate(state_sync): # type: ignore
9+
engine_adapter = state_sync.engine_adapter
10+
schema = state_sync.schema
11+
snapshots_table = f"{schema}._snapshots"
12+
13+
new_snapshots = []
14+
15+
for name, identifier, version, snapshot, kind_name in engine_adapter.fetchall(
16+
exp.select("name", "identifier", "version", "snapshot", "kind_name").from_(snapshots_table)
17+
):
18+
parsed_snapshot = json.loads(snapshot)
19+
model_kind = parsed_snapshot["model"]["kind"]
20+
if "path" in model_kind:
21+
model_kind["path"] = model_kind["path"].replace("\\", "/")
22+
23+
new_snapshots.append(
24+
{
25+
"name": name,
26+
"identifier": identifier,
27+
"version": version,
28+
"snapshot": json.dumps(parsed_snapshot),
29+
"kind_name": kind_name,
30+
}
31+
)
32+
33+
if new_snapshots:
34+
engine_adapter.delete_from(snapshots_table, "TRUE")
35+
36+
engine_adapter.insert_append(
37+
snapshots_table,
38+
pd.DataFrame(new_snapshots),
39+
columns_to_types={
40+
"name": exp.DataType.build("text"),
41+
"identifier": exp.DataType.build("text"),
42+
"version": exp.DataType.build("text"),
43+
"snapshot": exp.DataType.build("text"),
44+
"kind_name": exp.DataType.build("text"),
45+
},
46+
contains_json=True,
47+
)

tests/core/test_dialect.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,17 @@ def test_parse_jinja_with_semicolons():
197197
assert isinstance(expressions[2], JinjaStatement)
198198
assert isinstance(expressions[3], exp.Drop)
199199
assert isinstance(expressions[4], exp.Drop)
200+
201+
202+
def test_seed():
203+
expressions = parse(
204+
"""
205+
MODEL (
206+
kind SEED (
207+
path '..\..\..\data\data.csv',
208+
),
209+
);
210+
"""
211+
)
212+
assert len(expressions) == 1
213+
assert "../../../data/data.csv" in expressions[0].sql()

0 commit comments

Comments
 (0)