Skip to content

Commit 6217a61

Browse files
authored
Fix: Serialization of the ConnectionConfig objects (#2214)
1 parent 7a5ede0 commit 6217a61

4 files changed

Lines changed: 48 additions & 9 deletions

File tree

sqlmesh/core/config/connection.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from sqlmesh.core.engine_adapter import EngineAdapter
2525
from sqlmesh.utils.errors import ConfigError
2626
from sqlmesh.utils.pydantic import (
27+
PYDANTIC_MAJOR_VERSION,
2728
field_validator,
2829
model_validator,
2930
model_validator_v1_args,
@@ -42,9 +43,6 @@ class ConnectionConfig(abc.ABC, BaseConfig):
4243
concurrent_tasks: int
4344
register_comments: bool
4445

45-
# Pydantic V2 does not include type field in dict unless also in base class
46-
type_: str = Field(alias="type", default="none")
47-
4846
@property
4947
@abc.abstractmethod
5048
def _connection_kwargs_keys(self) -> t.Set[str]:
@@ -1276,3 +1274,16 @@ def _connection_config_validator(
12761274
mode="before",
12771275
check_fields=False,
12781276
)(_connection_config_validator)
1277+
1278+
1279+
if t.TYPE_CHECKING:
1280+
# TypeAlias hasn't been introduced until Python 3.10 which means that we can't use it
1281+
# outside the TYPE_CHECKING guard.
1282+
SerializableConnectionConfig: t.TypeAlias = ConnectionConfig # type: ignore
1283+
elif PYDANTIC_MAJOR_VERSION >= 2:
1284+
import pydantic
1285+
1286+
# Workaround for https://docs.pydantic.dev/latest/concepts/serialization/#serializing-with-duck-typing
1287+
SerializableConnectionConfig = pydantic.SerializeAsAny[ConnectionConfig] # type: ignore
1288+
else:
1289+
SerializableConnectionConfig = ConnectionConfig # type: ignore

sqlmesh/core/config/gateway.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
from sqlmesh.core import constants as c
66
from sqlmesh.core.config.base import BaseConfig
7-
from sqlmesh.core.config.connection import ConnectionConfig, connection_config_validator
7+
from sqlmesh.core.config.connection import (
8+
SerializableConnectionConfig,
9+
connection_config_validator,
10+
)
811
from sqlmesh.core.config.scheduler import SchedulerConfig
912

1013

@@ -22,9 +25,9 @@ class GatewayConfig(BaseConfig):
2225
then no schema name is used and therefore the default schema defined for the connection will be used
2326
"""
2427

25-
connection: t.Optional[ConnectionConfig] = None
26-
state_connection: t.Optional[ConnectionConfig] = None
27-
test_connection: t.Optional[ConnectionConfig] = None
28+
connection: t.Optional[SerializableConnectionConfig] = None
29+
state_connection: t.Optional[SerializableConnectionConfig] = None
30+
test_connection: t.Optional[SerializableConnectionConfig] = None
2831
scheduler: t.Optional[SchedulerConfig] = None
2932
state_schema: t.Optional[str] = c.SQLMESH
3033

sqlmesh/core/config/root.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from sqlmesh.core.config.connection import (
1818
ConnectionConfig,
1919
DuckDBConnectionConfig,
20+
SerializableConnectionConfig,
2021
connection_config_validator,
2122
)
2223
from sqlmesh.core.config.feature_flag import FeatureFlag
@@ -71,8 +72,8 @@ class Config(BaseConfig):
7172
"""
7273

7374
gateways: t.Dict[str, GatewayConfig] = {"": GatewayConfig()}
74-
default_connection: ConnectionConfig = DuckDBConnectionConfig()
75-
default_test_connection_: t.Optional[ConnectionConfig] = Field(
75+
default_connection: SerializableConnectionConfig = DuckDBConnectionConfig()
76+
default_test_connection_: t.Optional[SerializableConnectionConfig] = Field(
7677
default=None, alias="default_test_connection"
7778
)
7879
default_scheduler: SchedulerConfig = BuiltInSchedulerConfig()

tests/core/test_config.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,27 @@ class DerivedConfig(Config):
437437
},
438438
model_defaults=ModelDefaultsConfig(dialect=""),
439439
)
440+
441+
442+
def test_connection_config_serialization():
443+
config = Config(
444+
default_connection=DuckDBConnectionConfig(database="my_db"),
445+
default_test_connection=DuckDBConnectionConfig(database="my_test_db"),
446+
)
447+
serialized = config.dict()
448+
assert serialized["default_connection"] == {
449+
"concurrent_tasks": 1,
450+
"register_comments": True,
451+
"type": "duckdb",
452+
"extensions": [],
453+
"connector_config": {},
454+
"database": "my_db",
455+
}
456+
assert serialized["default_test_connection"] == {
457+
"concurrent_tasks": 1,
458+
"register_comments": True,
459+
"type": "duckdb",
460+
"extensions": [],
461+
"connector_config": {},
462+
"database": "my_test_db",
463+
}

0 commit comments

Comments
 (0)