Skip to content

Commit 029d8d5

Browse files
authored
Revert "Feat(experimental): DBT project conversion (#4495)" (#5246)
1 parent 54d21eb commit 029d8d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+46
-3738
lines changed

sqlmesh/cli/main.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
"rollback",
4040
"run",
4141
"table_name",
42-
"dbt",
4342
)
4443
SKIP_CONTEXT_COMMANDS = ("init", "ui")
4544

@@ -1307,39 +1306,3 @@ def state_import(obj: Context, input_file: Path, replace: bool, no_confirm: bool
13071306
"""Import a state export file back into the state database"""
13081307
confirm = not no_confirm
13091308
obj.import_state(input_file=input_file, clear=replace, confirm=confirm)
1310-
1311-
1312-
@cli.group(no_args_is_help=True, hidden=True)
1313-
def dbt() -> None:
1314-
"""Commands for doing dbt-specific things"""
1315-
pass
1316-
1317-
1318-
@dbt.command("convert")
1319-
@click.option(
1320-
"-i",
1321-
"--input-dir",
1322-
help="Path to the DBT project",
1323-
required=True,
1324-
type=click.Path(exists=True, dir_okay=True, file_okay=False, readable=True, path_type=Path),
1325-
)
1326-
@click.option(
1327-
"-o",
1328-
"--output-dir",
1329-
required=True,
1330-
help="Path to write out the converted SQLMesh project",
1331-
type=click.Path(exists=False, dir_okay=True, file_okay=False, readable=True, path_type=Path),
1332-
)
1333-
@click.option("--no-prompts", is_flag=True, help="Disable interactive prompts", default=False)
1334-
@click.pass_obj
1335-
@error_handler
1336-
@cli_analytics
1337-
def dbt_convert(obj: Context, input_dir: Path, output_dir: Path, no_prompts: bool) -> None:
1338-
"""Convert a DBT project to a SQLMesh project"""
1339-
from sqlmesh.dbt.converter.convert import convert_project_files
1340-
1341-
convert_project_files(
1342-
input_dir.absolute(),
1343-
output_dir.absolute(),
1344-
no_prompts=no_prompts,
1345-
)

sqlmesh/core/config/root.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
scheduler_config_validator,
4343
)
4444
from sqlmesh.core.config.ui import UIConfig
45-
from sqlmesh.core.loader import Loader, SqlMeshLoader, MigratedDbtProjectLoader
45+
from sqlmesh.core.loader import Loader, SqlMeshLoader
4646
from sqlmesh.core.notification_target import NotificationTarget
4747
from sqlmesh.core.user import User
4848
from sqlmesh.utils.date import to_timestamp, now
@@ -227,13 +227,6 @@ def _normalize_and_validate_fields(cls, data: t.Any) -> t.Any:
227227
f"^{k}$": v for k, v in physical_schema_override.items()
228228
}
229229

230-
if (
231-
(variables := data.get("variables", ""))
232-
and isinstance(variables, dict)
233-
and c.MIGRATED_DBT_PROJECT_NAME in variables
234-
):
235-
data["loader"] = MigratedDbtProjectLoader
236-
237230
return data
238231

239232
@model_validator(mode="after")

sqlmesh/core/constants.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
MAX_MODEL_DEFINITION_SIZE = 10000
3333
"""Maximum number of characters in a model definition"""
3434

35-
MIGRATED_DBT_PROJECT_NAME = "__dbt_project_name__"
36-
MIGRATED_DBT_PACKAGES = "__dbt_packages__"
37-
3835

3936
# The maximum number of fork processes, used for loading projects
4037
# None means default to process pool, 1 means don't fork, :N is number of processes

sqlmesh/core/loader.py

Lines changed: 1 addition & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,7 @@
3838
from sqlmesh.core.test import ModelTestMetadata, filter_tests_by_patterns
3939
from sqlmesh.utils import UniqueKeyDict, sys_path
4040
from sqlmesh.utils.errors import ConfigError
41-
from sqlmesh.utils.jinja import (
42-
JinjaMacroRegistry,
43-
MacroExtractor,
44-
SQLMESH_DBT_COMPATIBILITY_PACKAGE,
45-
)
41+
from sqlmesh.utils.jinja import JinjaMacroRegistry, MacroExtractor
4642
from sqlmesh.utils.metaprogramming import import_python_file
4743
from sqlmesh.utils.pydantic import validation_error_message
4844
from sqlmesh.utils.process import create_process_pool_executor
@@ -561,7 +557,6 @@ def _load_sql_models(
561557
signals: UniqueKeyDict[str, signal],
562558
cache: CacheBase,
563559
gateway: t.Optional[str],
564-
loading_default_kwargs: t.Optional[t.Dict[str, t.Any]] = None,
565560
) -> UniqueKeyDict[str, Model]:
566561
"""Loads the sql models into a Dict"""
567562
models: UniqueKeyDict[str, Model] = UniqueKeyDict("models")
@@ -604,7 +599,6 @@ def _load_sql_models(
604599
signal_definitions=signals,
605600
default_catalog_per_gateway=self.context.default_catalog_per_gateway,
606601
virtual_environment_mode=self.config.virtual_environment_mode,
607-
**loading_default_kwargs or {},
608602
)
609603

610604
with create_process_pool_executor(
@@ -971,104 +965,3 @@ def _model_cache_entry_id(self, model_path: Path) -> str:
971965
self._loader.context.gateway or self._loader.config.default_gateway_name,
972966
]
973967
)
974-
975-
976-
class MigratedDbtProjectLoader(SqlMeshLoader):
977-
@property
978-
def migrated_dbt_project_name(self) -> str:
979-
return self.config.variables[c.MIGRATED_DBT_PROJECT_NAME]
980-
981-
def _load_scripts(self) -> t.Tuple[MacroRegistry, JinjaMacroRegistry]:
982-
from sqlmesh.dbt.converter.common import infer_dbt_package_from_path
983-
from sqlmesh.dbt.target import TARGET_TYPE_TO_CONFIG_CLASS
984-
985-
# Store a copy of the macro registry
986-
standard_macros = macro.get_registry()
987-
988-
jinja_macros = JinjaMacroRegistry(
989-
create_builtins_module=SQLMESH_DBT_COMPATIBILITY_PACKAGE,
990-
top_level_packages=["dbt", self.migrated_dbt_project_name],
991-
)
992-
extractor = MacroExtractor()
993-
994-
macros_max_mtime: t.Optional[float] = None
995-
996-
for path in self._glob_paths(
997-
self.config_path / c.MACROS,
998-
ignore_patterns=self.config.ignore_patterns,
999-
extension=".py",
1000-
):
1001-
if import_python_file(path, self.config_path):
1002-
self._track_file(path)
1003-
macro_file_mtime = self._path_mtimes[path]
1004-
macros_max_mtime = (
1005-
max(macros_max_mtime, macro_file_mtime)
1006-
if macros_max_mtime
1007-
else macro_file_mtime
1008-
)
1009-
1010-
for path in self._glob_paths(
1011-
self.config_path / c.MACROS,
1012-
ignore_patterns=self.config.ignore_patterns,
1013-
extension=".sql",
1014-
):
1015-
self._track_file(path)
1016-
macro_file_mtime = self._path_mtimes[path]
1017-
macros_max_mtime = (
1018-
max(macros_max_mtime, macro_file_mtime) if macros_max_mtime else macro_file_mtime
1019-
)
1020-
1021-
with open(path, "r", encoding="utf-8") as file:
1022-
try:
1023-
package = infer_dbt_package_from_path(path) or self.migrated_dbt_project_name
1024-
1025-
jinja_macros.add_macros(
1026-
extractor.extract(file.read(), dialect=self.config.model_defaults.dialect),
1027-
package=package,
1028-
)
1029-
except Exception as e:
1030-
raise ConfigError(f"Failed to load macro file: {e}", path)
1031-
1032-
self._macros_max_mtime = macros_max_mtime
1033-
1034-
macros = macro.get_registry()
1035-
macro.set_registry(standard_macros)
1036-
1037-
connection_config = self.context.connection_config
1038-
# this triggers the DBT create_builtins_module to have a `target` property which is required for a bunch of DBT macros to work
1039-
if dbt_config_type := TARGET_TYPE_TO_CONFIG_CLASS.get(connection_config.type_):
1040-
try:
1041-
jinja_macros.add_globals(
1042-
{
1043-
"target": dbt_config_type.from_sqlmesh(
1044-
connection_config,
1045-
name=self.config.default_gateway_name,
1046-
).attribute_dict()
1047-
}
1048-
)
1049-
except NotImplementedError:
1050-
raise ConfigError(f"Unsupported dbt target type: {connection_config.type_}")
1051-
1052-
return macros, jinja_macros
1053-
1054-
def _load_sql_models(
1055-
self,
1056-
macros: MacroRegistry,
1057-
jinja_macros: JinjaMacroRegistry,
1058-
audits: UniqueKeyDict[str, ModelAudit],
1059-
signals: UniqueKeyDict[str, signal],
1060-
cache: CacheBase,
1061-
gateway: t.Optional[str],
1062-
loading_default_kwargs: t.Optional[t.Dict[str, t.Any]] = None,
1063-
) -> UniqueKeyDict[str, Model]:
1064-
return super()._load_sql_models(
1065-
macros=macros,
1066-
jinja_macros=jinja_macros,
1067-
audits=audits,
1068-
signals=signals,
1069-
cache=cache,
1070-
gateway=gateway,
1071-
loading_default_kwargs=dict(
1072-
migrated_dbt_project_name=self.migrated_dbt_project_name,
1073-
),
1074-
)

sqlmesh/core/model/definition.py

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,6 @@ def load_sql_based_model(
20612061
variables: t.Optional[t.Dict[str, t.Any]] = None,
20622062
infer_names: t.Optional[bool] = False,
20632063
blueprint_variables: t.Optional[t.Dict[str, t.Any]] = None,
2064-
migrated_dbt_project_name: t.Optional[str] = None,
20652064
**kwargs: t.Any,
20662065
) -> Model:
20672066
"""Load a model from a parsed SQLMesh model SQL file.
@@ -2239,7 +2238,6 @@ def load_sql_based_model(
22392238
query_or_seed_insert,
22402239
kind=kind,
22412240
time_column_format=time_column_format,
2242-
migrated_dbt_project_name=migrated_dbt_project_name,
22432241
**common_kwargs,
22442242
)
22452243

@@ -2451,7 +2449,6 @@ def _create_model(
24512449
signal_definitions: t.Optional[SignalRegistry] = None,
24522450
variables: t.Optional[t.Dict[str, t.Any]] = None,
24532451
blueprint_variables: t.Optional[t.Dict[str, t.Any]] = None,
2454-
migrated_dbt_project_name: t.Optional[str] = None,
24552452
**kwargs: t.Any,
24562453
) -> Model:
24572454
validate_extra_and_required_fields(
@@ -2531,31 +2528,16 @@ def _create_model(
25312528

25322529
if jinja_macros:
25332530
jinja_macros = (
2534-
jinja_macros
2535-
if jinja_macros.trimmed
2536-
else jinja_macros.trim(jinja_macro_references, package=migrated_dbt_project_name)
2531+
jinja_macros if jinja_macros.trimmed else jinja_macros.trim(jinja_macro_references)
25372532
)
25382533
else:
25392534
jinja_macros = JinjaMacroRegistry()
25402535

2541-
if migrated_dbt_project_name:
2542-
# extract {{ var() }} references used in all jinja macro dependencies to check for any variables specific
2543-
# to a migrated DBT package and resolve them accordingly
2544-
# vars are added into __sqlmesh_vars__ in the Python env so that the native SQLMesh var() function can resolve them
2545-
variables = variables or {}
2546-
2547-
nested_macro_used_variables, flattened_package_variables = (
2548-
_extract_migrated_dbt_variable_references(jinja_macros, variables)
2536+
for jinja_macro in jinja_macros.root_macros.values():
2537+
referenced_variables.update(
2538+
extract_macro_references_and_variables(jinja_macro.definition)[1]
25492539
)
25502540

2551-
referenced_variables.update(nested_macro_used_variables)
2552-
variables.update(flattened_package_variables)
2553-
else:
2554-
for jinja_macro in jinja_macros.root_macros.values():
2555-
referenced_variables.update(
2556-
extract_macro_references_and_variables(jinja_macro.definition)[1]
2557-
)
2558-
25592541
# Merge model-specific audits with default audits
25602542
if default_audits := defaults.pop("audits", None):
25612543
kwargs["audits"] = default_audits + d.extract_function_calls(kwargs.pop("audits", []))
@@ -2943,7 +2925,7 @@ def render_expression(
29432925
"cron_tz": lambda value: exp.Literal.string(value),
29442926
"partitioned_by_": _single_expr_or_tuple,
29452927
"clustered_by": _single_expr_or_tuple,
2946-
"depends_on_": lambda value: exp.Tuple(expressions=sorted(value)) if value else "()",
2928+
"depends_on_": lambda value: exp.Tuple(expressions=sorted(value)),
29472929
"pre": _list_of_calls_to_exp,
29482930
"post": _list_of_calls_to_exp,
29492931
"audits": _list_of_calls_to_exp,
@@ -3020,37 +3002,4 @@ def clickhouse_partition_func(
30203002
)
30213003

30223004

3023-
def _extract_migrated_dbt_variable_references(
3024-
jinja_macros: JinjaMacroRegistry, project_variables: t.Dict[str, t.Any]
3025-
) -> t.Tuple[t.Set[str], t.Dict[str, t.Any]]:
3026-
if not jinja_macros.trimmed:
3027-
raise ValueError("Expecting a trimmed JinjaMacroRegistry")
3028-
3029-
used_variables = set()
3030-
# note: JinjaMacroRegistry is trimmed here so "all_macros" should be just be all the macros used by this model
3031-
for _, _, jinja_macro in jinja_macros.all_macros:
3032-
_, extracted_variable_names = extract_macro_references_and_variables(jinja_macro.definition)
3033-
used_variables.update(extracted_variable_names)
3034-
3035-
flattened = {}
3036-
if (dbt_package_variables := project_variables.get(c.MIGRATED_DBT_PACKAGES)) and isinstance(
3037-
dbt_package_variables, dict
3038-
):
3039-
# flatten the nested dict structure from the migrated dbt package variables in the SQLmesh config into __dbt_packages.<package>.<variable>
3040-
# to match what extract_macro_references_and_variables() returns. This allows the usage checks in create_python_env() to work
3041-
def _flatten(prefix: str, root: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
3042-
acc = {}
3043-
for k, v in root.items():
3044-
key_with_prefix = f"{prefix}.{k}"
3045-
if isinstance(v, dict):
3046-
acc.update(_flatten(key_with_prefix, v))
3047-
else:
3048-
acc[key_with_prefix] = v
3049-
return acc
3050-
3051-
flattened = _flatten(c.MIGRATED_DBT_PACKAGES, dbt_package_variables)
3052-
3053-
return used_variables, flattened
3054-
3055-
30563005
TIME_COL_PARTITION_FUNC = {"clickhouse": clickhouse_partition_func}

sqlmesh/core/model/kind.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from enum import Enum
55
from typing_extensions import Self
66

7-
from pydantic import Field, BeforeValidator
7+
from pydantic import Field
88
from sqlglot import exp
99
from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
1010
from sqlglot.optimizer.qualify_columns import quote_identifiers
@@ -33,7 +33,6 @@
3333
field_validator,
3434
get_dialect,
3535
validate_string,
36-
positive_int_validator,
3736
validate_expression,
3837
)
3938

@@ -505,7 +504,7 @@ class IncrementalByUniqueKeyKind(_IncrementalBy):
505504
unique_key: SQLGlotListOfFields
506505
when_matched: t.Optional[exp.Whens] = None
507506
merge_filter: t.Optional[exp.Expression] = None
508-
batch_concurrency: t.Annotated[t.Literal[1], BeforeValidator(positive_int_validator)] = 1
507+
batch_concurrency: t.Literal[1] = 1
509508

510509
@field_validator("when_matched", mode="before")
511510
def _when_matched_validator(

sqlmesh/core/renderer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ def _resolve_table(table: str | exp.Table) -> str:
179179
)
180180

181181
render_kwargs = {
182-
"dialect": self._dialect,
183182
**date_dict(
184183
to_datetime(execution_time or c.EPOCH),
185184
start_time,

sqlmesh/core/test/definition.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,9 @@ def _create_df(
648648
if partial:
649649
columns = referenced_columns
650650

651-
return pd.DataFrame.from_records(rows, columns=columns)
651+
return pd.DataFrame.from_records(
652+
rows, columns=[str(c) for c in columns] if columns else None
653+
)
652654

653655
def _add_missing_columns(
654656
self, query: exp.Query, all_columns: t.Optional[t.Collection[str]] = None

sqlmesh/dbt/adapter.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ def __init__(
4040
self.jinja_globals = jinja_globals.copy() if jinja_globals else {}
4141
self.jinja_globals["adapter"] = self
4242
self.project_dialect = project_dialect
43-
self.jinja_globals["dialect"] = (
44-
project_dialect # so the dialect is available in the jinja env created by self.dispatch()
45-
)
4643
self.quote_policy = quote_policy or Policy()
4744

4845
@abc.abstractmethod

sqlmesh/dbt/builtin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class Var:
157157
def __init__(self, variables: t.Dict[str, t.Any]) -> None:
158158
self.variables = variables
159159

160-
def __call__(self, name: str, default: t.Optional[t.Any] = None, **kwargs: t.Any) -> t.Any:
160+
def __call__(self, name: str, default: t.Optional[t.Any] = None) -> t.Any:
161161
return self.variables.get(name, default)
162162

163163
def has_var(self, name: str) -> bool:

0 commit comments

Comments
 (0)