Skip to content

Commit f8a572d

Browse files
committed
Handle special characters in gateway name
1 parent 8601909 commit f8a572d

2 files changed

Lines changed: 48 additions & 77 deletions

File tree

sqlmesh/utils/yaml.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,20 @@ def load(
4949
) -> t.Dict:
5050
"""Loads a YAML object from either a raw string or a file."""
5151
path: t.Optional[Path] = None
52+
yaml = YAML()
5253

5354
if isinstance(source, Path):
5455
path = source
5556
with open(source, "r", encoding="utf-8") as file:
5657
source = file.read()
5758

5859
if get_variables:
59-
gateway = GATEWAY_PATTERN.search(source)
60-
variables = get_variables(config, gateway.group(1) if gateway else None)
60+
# If the user has specified a quoted/escaped gateway (e.g. "gateway: 'ma\tin'"), we need to
61+
# parse it as YAML to match the gateway name stored in the config
62+
gateway_line = GATEWAY_PATTERN.search(source)
63+
gateway = yaml.load(gateway_line.group(0))["gateway"] if gateway_line else None
64+
65+
variables = get_variables(config, gateway)
6166

6267
if render_jinja:
6368
source = ENVIRONMENT.from_string(source).render(
@@ -67,7 +72,6 @@ def load(
6772
}
6873
)
6974

70-
yaml = YAML()
7175
yaml.allow_duplicate_keys = allow_duplicate_keys
7276
contents = yaml.load(source)
7377
if contents is None:

tests/core/test_test.py

Lines changed: 41 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,32 +1575,15 @@ def test_variable_usage(tmp_path: Path) -> None:
15751575
meta="MODEL (name gold_db.sch.a, kind INCREMENTAL_BY_TIME_RANGE(time_column ds))",
15761576
)
15771577

1578-
def init_context(config: Config, **kwargs):
1579-
context = Context(paths=tmp_path, config=config, **kwargs)
1580-
context.upsert_model(parent)
1581-
context.upsert_model(child)
1582-
return context
1583-
1584-
# Case 1: Test root variables
1585-
config = Config(
1586-
default_connection=DuckDBConnectionConfig(),
1587-
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
1588-
variables=variables,
1589-
)
1590-
1591-
context = init_context(config)
1592-
1593-
test_file = tmp_path / "tests" / "test_parameterized_model_names.yaml"
1594-
test_file.write_text(
1595-
"""
1578+
test_text = """
15961579
test_parameterized_model_names:
1597-
model: {{ var('gold') }}.sch.a
1580+
model: {{{{ var('gold') }}}}.sch.a {gateway}
15981581
vars:
15991582
myvar: True
16001583
start_ds: 2022-01-01
16011584
end_ds: 2022-01-03
16021585
inputs:
1603-
{{ var('silver') }}.sch.b:
1586+
{{{{ var('silver') }}}}.sch.b:
16041587
- ds: 2022-01-01
16051588
id: 1
16061589
- ds: 2022-01-01
@@ -1610,17 +1593,31 @@ def init_context(config: Config, **kwargs):
16101593
- ds: 2022-01-01
16111594
id: 1
16121595
- ds: 2022-01-01
1613-
id: 2
1614-
"""
1615-
)
1596+
id: 2"""
16161597

1617-
results = context.test()
1598+
test_file = tmp_path / "tests" / "test_parameterized_model_names.yaml"
1599+
1600+
def init_context_and_validate_results(config: Config, **kwargs):
1601+
context = Context(paths=tmp_path, config=config, **kwargs)
1602+
context.upsert_model(parent)
1603+
context.upsert_model(child)
1604+
1605+
results = context.test()
1606+
1607+
assert not results.failures
1608+
assert not results.errors
1609+
assert len(results.successes) == 2
1610+
1611+
# Case 1: Test root variables
1612+
config = Config(
1613+
default_connection=DuckDBConnectionConfig(),
1614+
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
1615+
variables=variables,
1616+
)
16181617

1619-
assert not results.failures
1620-
assert not results.errors
1618+
test_file.write_text(test_text.format(gateway=""))
16211619

1622-
# The example project has one test and we added another one above
1623-
assert len(results.successes) == 2
1620+
init_context_and_validate_results(config)
16241621

16251622
# Case 2: Test gateway variables
16261623
config = Config(
@@ -1629,14 +1626,7 @@ def init_context(config: Config, **kwargs):
16291626
},
16301627
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
16311628
)
1632-
1633-
context = init_context(config, gateway="main")
1634-
1635-
results = context.test()
1636-
1637-
assert not results.failures
1638-
assert not results.errors
1639-
assert len(results.successes) == 2
1629+
init_context_and_validate_results(config)
16401630

16411631
# Case 3: Test gateway variables overriding root variables
16421632
config = Config(
@@ -1646,41 +1636,9 @@ def init_context(config: Config, **kwargs):
16461636
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
16471637
variables=incorrect_variables,
16481638
)
1649-
1650-
context = init_context(config, gateway="main")
1651-
1652-
results = context.test()
1653-
1654-
assert not results.failures
1655-
assert not results.errors
1656-
assert len(results.successes) == 2
1639+
init_context_and_validate_results(config, gateway="main")
16571640

16581641
# Case 4: Use variable from the defined gateway
1659-
test_file = tmp_path / "tests" / "test_parameterized_model_names.yaml"
1660-
test_file.write_text(
1661-
"""
1662-
test_parameterized_model_names:
1663-
model: {{ var('gold') }}.sch.a
1664-
gateway: secondary
1665-
vars:
1666-
myvar: True
1667-
start_ds: 2022-01-01
1668-
end_ds: 2022-01-03
1669-
inputs:
1670-
{{ var('silver') }}.sch.b:
1671-
- ds: 2022-01-01
1672-
id: 1
1673-
- ds: 2022-01-01
1674-
id: 2
1675-
outputs:
1676-
query:
1677-
- ds: 2022-01-01
1678-
id: 1
1679-
- ds: 2022-01-01
1680-
id: 2
1681-
"""
1682-
)
1683-
16841642
config = Config(
16851643
gateways={
16861644
"main": GatewayConfig(
@@ -1691,13 +1649,22 @@ def init_context(config: Config, **kwargs):
16911649
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
16921650
)
16931651

1694-
context = init_context(config, gateway="main")
1652+
test_file.write_text(test_text.format(gateway="\n gateway: secondary"))
1653+
init_context_and_validate_results(config, gateway="main")
16951654

1696-
results = context.test()
1655+
# Case 5: Use gateways with escaped characters
1656+
config = Config(
1657+
gateways={
1658+
"main": GatewayConfig(
1659+
connection=DuckDBConnectionConfig(), variables=incorrect_variables
1660+
),
1661+
"secon\tdary": GatewayConfig(connection=DuckDBConnectionConfig(), variables=variables),
1662+
},
1663+
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
1664+
)
16971665

1698-
assert not results.failures
1699-
assert not results.errors
1700-
assert len(results.successes) == 2
1666+
test_file.write_text(test_text.format(gateway='\n gateway: "secon\\tdary"'))
1667+
init_context_and_validate_results(config, gateway="main")
17011668

17021669

17031670
def test_custom_testing_schema(mocker: MockerFixture) -> None:

0 commit comments

Comments
 (0)