Skip to content

Commit d490134

Browse files
authored
Merge branch 'main' into feat/invalidate-cleanup-snapshots
2 parents ff5f4a9 + e689df5 commit d490134

22 files changed

Lines changed: 415 additions & 44 deletions

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ install-dev-dbt-%:
6363
fi; \
6464
if [ "$$version" = "1.3.0" ]; then \
6565
echo "Applying overrides for dbt $$version - upgrading google-cloud-bigquery"; \
66-
$(PIP) install 'google-cloud-bigquery>=3.0.0' --upgrade; \
66+
$(PIP) install 'google-cloud-bigquery>=3.0.0' \
67+
'pyOpenSSL>=24.0.0' --upgrade; \
6768
fi; \
6869
mv pyproject.toml.backup pyproject.toml; \
6970
echo "Restored original pyproject.toml"

docs/prerequisites.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This page describes the system prerequisites needed to run SQLMesh and provides
44

55
## SQLMesh prerequisites
66

7-
You'll need Python 3.8 or higher to use SQLMesh. You can check your python version by running the following command:
7+
You'll need Python 3.9 or higher to use SQLMesh. You can check your python version by running the following command:
88
```bash
99
python3 --version
1010
```

pyproject.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ authors = [{ name = "SQLMesh Contributors" }]
77
license = { file = "LICENSE" }
88
requires-python = ">= 3.9"
99
dependencies = [
10-
"astor",
1110
"click",
1211
"croniter",
1312
"duckdb>=0.10.0,!=0.10.3",
@@ -202,7 +201,6 @@ disable_error_code = "annotation-unchecked"
202201
[[tool.mypy.overrides]]
203202
module = [
204203
"api.*",
205-
"astor.*",
206204
"IPython.*",
207205
"hyperscript.*",
208206
"py.*",

sqlmesh/core/config/connection.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from sys import version_info
1414

1515
import pydantic
16+
from pydantic import Field, computed_field
1617
from packaging import version
17-
from pydantic import Field
1818
from pydantic_core import from_json
1919
from sqlglot import exp
2020
from sqlglot.errors import ParseError
@@ -110,7 +110,14 @@ class ConnectionConfig(abc.ABC, BaseConfig):
110110
catalog_type_overrides: t.Optional[t.Dict[str, str]] = None
111111

112112
# Whether to share a single connection across threads or create a new connection per thread.
113-
shared_connection: t.ClassVar[bool] = False
113+
#
114+
# MyPy throws a "Decorators on top of @property are not supported" error despite this being a
115+
# valid decoration, and Pydantic recommend disabling the MyPy hint for this reason - see:
116+
# https://pydantic.dev/docs/validation/2.0/usage/computed_fields/
117+
@computed_field # type: ignore[prop-decorator]
118+
@property
119+
def shared_connection(self) -> bool:
120+
return False
114121

115122
@property
116123
@abc.abstractmethod
@@ -311,7 +318,10 @@ class BaseDuckDBConnectionConfig(ConnectionConfig):
311318

312319
token: t.Optional[str] = None
313320

314-
shared_connection: t.ClassVar[bool] = True
321+
@computed_field # type: ignore[prop-decorator]
322+
@property
323+
def shared_connection(self) -> bool:
324+
return True
315325

316326
_data_file_to_adapter: t.ClassVar[t.Dict[str, EngineAdapter]] = {}
317327

@@ -820,11 +830,15 @@ class DatabricksConnectionConfig(ConnectionConfig):
820830
DISPLAY_NAME: t.ClassVar[t.Literal["Databricks"]] = "Databricks"
821831
DISPLAY_ORDER: t.ClassVar[t.Literal[3]] = 3
822832

823-
shared_connection: t.ClassVar[bool] = True
824-
825833
_concurrent_tasks_validator = concurrent_tasks_validator
826834
_http_headers_validator = http_headers_validator
827835

836+
@computed_field # type: ignore[prop-decorator]
837+
@property
838+
def shared_connection(self) -> bool:
839+
"""The connection should only be shared if U2M OAuth is being used"""
840+
return self.auth_type is not None and self.oauth_client_secret is None
841+
828842
@model_validator(mode="before")
829843
def _databricks_connect_validator(cls, data: t.Any) -> t.Any:
830844
# SQLQueryContextLogger will output any error SQL queries even if they are in a try/except block.

sqlmesh/core/config/loader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,4 @@ def convert_config_type(
272272
config_obj: Config,
273273
config_type: t.Type[C],
274274
) -> C:
275-
return config_type.parse_obj(config_obj.dict())
275+
return config_type.parse_obj(config_obj.dict(exclude_computed_fields=True))

sqlmesh/core/engine_adapter/databricks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def _set_spark_engine_adapter_if_needed(self) -> None:
154154
host=self._extra_config["databricks_connect_server_hostname"],
155155
token=self._extra_config.get("databricks_connect_access_token"),
156156
)
157-
if "databricks_connect_use_serverless" in self._extra_config:
157+
if self._extra_config.get("databricks_connect_use_serverless"):
158158
connect_kwargs["serverless"] = True
159159
else:
160160
connect_kwargs["cluster_id"] = self._extra_config["databricks_connect_cluster_id"]

sqlmesh/core/model/common.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import typing as t
55
from pathlib import Path
66

7-
from astor import to_source
87
from difflib import get_close_matches
98
from sqlglot import exp
109
from sqlglot.helper import ensure_list
@@ -387,7 +386,7 @@ def get_first_arg(keyword_arg_name: str) -> t.Any:
387386
)
388387

389388
try:
390-
expression = to_source(first_arg)
389+
expression = ast.unparse(t.cast(ast.expr, first_arg))
391390
return eval(expression, env, local_env)
392391
except Exception:
393392
if strict_resolution:

sqlmesh/core/model/definition.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,7 @@ def render(
17121712

17131713
def render_seed(self) -> t.Iterator[QueryOrDF]:
17141714
import numpy as np
1715+
import pandas as pd
17151716

17161717
self._ensure_hydrated()
17171718

@@ -1752,8 +1753,6 @@ def render_seed(self) -> t.Iterator[QueryOrDF]:
17521753

17531754
# convert all date/time types to native pandas timestamp
17541755
for column in [*date_columns, *datetime_columns]:
1755-
import pandas as pd
1756-
17571756
df[column] = pd.to_datetime(df[column], infer_datetime_format=True, errors="ignore") # type: ignore
17581757

17591758
# extract datetime.date from pandas timestamp for DATE columns
@@ -1769,7 +1768,7 @@ def render_seed(self) -> t.Iterator[QueryOrDF]:
17691768
)
17701769

17711770
for column in bool_columns:
1772-
df[column] = df[column].apply(lambda i: str_to_bool(str(i)))
1771+
df[column] = df[column].apply(lambda i: None if pd.isna(i) else str_to_bool(str(i)))
17731772

17741773
df.loc[:, string_columns] = df[string_columns].mask(
17751774
cond=lambda x: x.notna(), # type: ignore

sqlmesh/core/model/kind.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ def to_property(self, dialect: str = "") -> exp.Property:
341341
@classmethod
342342
def create(cls, v: t.Any, dialect: str) -> Self:
343343
if isinstance(v, exp.Tuple):
344+
if not v.expressions:
345+
raise ConfigError("Time Column cannot be empty.")
344346
column_expr = v.expressions[0]
345347
column = (
346348
exp.column(column_expr) if isinstance(column_expr, exp.Identifier) else column_expr

sqlmesh/integrations/dlt.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ def generate_dlt_models_and_settings(
6363
if db_type == "filesystem":
6464
connection_config = None
6565
else:
66-
if dlt.__version__ >= "1.10.0":
67-
client = pipeline.destination_client()
68-
else:
69-
client = pipeline._sql_job_client(schema) # type: ignore
66+
client = pipeline.destination_client()
7067
config = client.config
7168
credentials = config.credentials
7269
configs = {

0 commit comments

Comments
 (0)