Skip to content

Commit deec9e9

Browse files
jontsaiclaude
andcommitted
Upgrade Pydantic from v1 to v2
This commit completes the migration from Pydantic v1 to v2, with the following changes: - Updated Pydantic model configuration syntax: - Changed `class Config:` to `model_config = ConfigDict()` in catalog.py - Updated imports to use `from pydantic import ConfigDict` - Fixed Pydantic v2 field requirements: - Added default values (= None) to all Optional fields without defaults in manifest.py - This is required in Pydantic v2 for proper model validation - Updated deprecated method calls: - Changed `.json()` to `.model_dump_json()` in executor.py - These methods serialize Pydantic models to JSON strings - Migrated vendor dependencies (dbt_artifacts_parser): - Replaced `constr()` with `Annotated[str, StringConstraints()]` across all manifest versions - Added `from typing_extensions import Annotated` imports - This follows Pydantic v2's recommended pattern for constrained types - Added .venv/ to .gitignore Testing: - Ran full test suite using .venv/bin/pytest - All 64 tests passed successfully - Verified Pydantic 2.12.0 compatibility setup.py already specified pydantic>=2.0,<3.0, so no dependency changes were needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent aa5d3df commit deec9e9

File tree

16 files changed

+72
-73
lines changed

16 files changed

+72
-73
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pyvenv*/
3333
sdist
3434
var
3535
venv*/
36+
.venv/
3637
wheelhouse
3738

3839
# Installer logs

src/datapilot/core/platforms/dbt/executor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ def run_llm_checks(self):
109109
self.token,
110110
self.instance_name,
111111
self.backend_url,
112-
self.manifest.json() if self.manifest else "",
113-
self.catalog.json() if self.catalog else "",
112+
self.manifest.model_dump_json() if self.manifest else "",
113+
self.catalog.model_dump_json() if self.catalog else "",
114114
check_names,
115115
)
116116
return llm_check_results

src/datapilot/core/platforms/dbt/schemas/catalog.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from typing import Optional
66
from typing import Union
77

8-
from pydantic.main import BaseModel
8+
from pydantic import BaseModel
9+
from pydantic import ConfigDict
910

1011
from vendor.dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogV1 as BaseCatalogV1
1112
from vendor.dbt_artifacts_parser.parsers.catalog.catalog_v1 import Metadata as BaseMetadata
@@ -59,15 +60,12 @@ class AltimateCatalogCatalogV1(BaseModel):
5960

6061
# Custom classes to handle extra fields in newer dbt versions
6162
class Metadata(BaseMetadata):
62-
class Config:
63-
extra = "allow" # Allow extra fields in metadata
63+
model_config = ConfigDict(extra="allow")
6464

6565

6666
class CatalogV1(BaseCatalogV1):
6767
metadata: Metadata # Use our custom metadata class
68-
69-
class Config:
70-
extra = "allow" # Allow extra fields
68+
model_config = ConfigDict(extra="allow")
7169

7270

7371
Catalog = CatalogV1

src/datapilot/core/platforms/dbt/schemas/manifest.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
class DBTVersion(BaseModel):
2626
MAJOR: int
2727
MINOR: int
28-
PATCH: Optional[int]
28+
PATCH: Optional[int] = None
2929

3030

3131
Manifest = Union[
@@ -64,8 +64,8 @@ class AltimateManifestColumnInfo(BaseModel):
6464

6565

6666
class AltimateFileHash(BaseModel):
67-
name: Optional[str]
68-
checksum: Optional[str]
67+
name: Optional[str] = None
68+
checksum: Optional[str] = None
6969

7070

7171
class AltimateResourceType(Enum):
@@ -118,8 +118,8 @@ class AltimateNodeConfig(BaseModel):
118118
materialized: Optional[str] = "view"
119119
incremental_strategy: Optional[Optional[str]] = None
120120
persist_docs: Optional[Dict[str, Any]] = None
121-
post_hook: Optional[List[AltimateHook]]
122-
pre_hook: Optional[List[AltimateHook]]
121+
post_hook: Optional[List[AltimateHook]] = None
122+
pre_hook: Optional[List[AltimateHook]] = None
123123
quoting: Optional[Dict[str, Any]] = None
124124
column_types: Optional[Dict[str, Any]] = None
125125
full_refresh: Optional[Optional[bool]] = None
@@ -128,7 +128,7 @@ class AltimateNodeConfig(BaseModel):
128128

129129

130130
class AltimateManifestNode(BaseModel):
131-
database: Optional[str]
131+
database: Optional[str] = None
132132
resource_type: AltimateResourceType
133133
schema_name: str
134134
name: str
@@ -141,7 +141,7 @@ class AltimateManifestNode(BaseModel):
141141
config: Optional[AltimateNodeConfig] = None
142142
raw_code: Optional[str] = ""
143143
language: Optional[str] = "sql"
144-
checksum: Optional[AltimateFileHash]
144+
checksum: Optional[AltimateFileHash] = None
145145
description: Optional[str] = ""
146146
columns: Optional[Dict[str, AltimateManifestColumnInfo]] = None
147147
relation_name: Optional[Optional[str]] = None
@@ -151,7 +151,7 @@ class AltimateManifestNode(BaseModel):
151151
compiled_path: Optional[Optional[str]] = None
152152
compiled: Optional[bool] = False
153153
compiled_code: Optional[Optional[str]] = None
154-
access: Optional[AltimateAccess]
154+
access: Optional[AltimateAccess] = None
155155
contract: Optional[AltimateDBTContract] = None
156156
meta: Optional[Dict[str, Any]] = None
157157
patch_path: Optional[Optional[str]] = None
@@ -190,10 +190,10 @@ class AltimateSourceConfig(BaseModel):
190190

191191

192192
class AltimateDeferRelation(BaseModel):
193-
database: Optional[str]
193+
database: Optional[str] = None
194194
schema_name: str
195195
alias: str
196-
relation_name: Optional[str]
196+
relation_name: Optional[str] = None
197197

198198

199199
class AltimateSeedConfig(BaseModel):
@@ -208,8 +208,8 @@ class AltimateSeedConfig(BaseModel):
208208
materialized: Optional[str] = "seed"
209209
incremental_strategy: Optional[Optional[str]] = None
210210
persist_docs: Optional[Dict[str, Any]] = None
211-
post_hook: Optional[List[AltimateHook]]
212-
pre_hook: Optional[List[AltimateHook]]
211+
post_hook: Optional[List[AltimateHook]] = None
212+
pre_hook: Optional[List[AltimateHook]] = None
213213
quoting: Optional[Dict[str, Any]] = None
214214
column_types: Optional[Dict[str, Any]] = None
215215
full_refresh: Optional[Optional[bool]] = None
@@ -225,7 +225,7 @@ class AltimateSeedConfig(BaseModel):
225225

226226

227227
class AltimateSeedNode(BaseModel):
228-
database: Optional[str]
228+
database: Optional[str] = None
229229
schema_name: str
230230
name: str
231231
resource_type: AltimateResourceType
@@ -235,7 +235,7 @@ class AltimateSeedNode(BaseModel):
235235
unique_id: str
236236
fqn: List[str]
237237
alias: str
238-
checksum: Optional[AltimateFileHash]
238+
checksum: Optional[AltimateFileHash] = None
239239
config: Optional[AltimateSeedConfig] = None
240240
tags: Optional[List[str]] = None
241241
description: Optional[str] = ""
@@ -257,7 +257,7 @@ class AltimateSeedNode(BaseModel):
257257

258258

259259
class AltimateManifestSourceNode(BaseModel):
260-
database: Optional[str]
260+
database: Optional[str] = None
261261
resource_type: AltimateResourceType
262262
schema_name: str
263263
name: str
@@ -379,7 +379,7 @@ class AltimateManifestTestNode(BaseModel):
379379
unique_id: str
380380
fqn: List[str]
381381
alias: str
382-
checksum: Optional[AltimateFileHash]
382+
checksum: Optional[AltimateFileHash] = None
383383
config: Optional[AltimateTestConfig] = None
384384
_event_status: Optional[Dict[str, Any]] = None
385385
tags: Optional[List[str]] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v1.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -26,7 +26,7 @@ class ManifestMetadata(BaseParserModel):
2626
invocation_id: Optional[str] = None
2727
env: Optional[dict[str, str]] = {}
2828
project_id: Optional[str] = Field(None, description="A unique identifier for the project")
29-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
29+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3030
None, description="A unique identifier for the user"
3131
)
3232
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -110,7 +110,7 @@ class TestConfig(BaseParserModel):
110110
database: Optional[str] = None
111111
tags: Optional[Union[list[str], str]] = []
112112
full_refresh: Optional[bool] = None
113-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
113+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
114114

115115

116116
class ResourceType2(Enum):

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v10.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -30,7 +30,7 @@ class ManifestMetadata(BaseParserModel):
3030
None,
3131
description="A unique identifier for the project, hashed from the project name",
3232
)
33-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
33+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3434
None, description="A unique identifier for the user"
3535
)
3636
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -148,7 +148,7 @@ class TestConfig(BaseParserModel):
148148
meta: Optional[dict[str, Any]] = {}
149149
group: Optional[str] = None
150150
materialized: Optional[str] = "test"
151-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
151+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
152152
store_failures: Optional[bool] = None
153153
where: Optional[str] = None
154154
limit: Optional[int] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v11.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from typing import Union
1111
from uuid import UUID
1212

13-
from pydantic import ConfigDict
13+
from pydantic import StringConstraints, ConfigDict
1414
from pydantic import Field
15-
from pydantic import constr
1615

1716
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
17+
from typing_extensions import Annotated
1818

1919

2020
class ManifestMetadata(BaseParserModel):
@@ -230,7 +230,7 @@ class TestConfig(BaseParserModel):
230230
meta: Optional[dict[str, Any]] = None
231231
group: Optional[str] = None
232232
materialized: Optional[str] = "test"
233-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
233+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
234234
store_failures: Optional[bool] = None
235235
store_failures_as: Optional[str] = None
236236
where: Optional[str] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v12.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from typing import Union
1111
from uuid import UUID
1212

13-
from pydantic import ConfigDict
13+
from pydantic import StringConstraints, ConfigDict
1414
from pydantic import Field
15-
from pydantic import constr
1615

1716
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
17+
from typing_extensions import Annotated
1818

1919

2020
class Quoting(BaseParserModel):
@@ -475,7 +475,7 @@ class Config5(BaseParserModel):
475475
meta: Optional[dict[str, Any]] = None
476476
group: Optional[str] = None
477477
materialized: Optional[str] = "test"
478-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
478+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
479479
store_failures: Optional[bool] = None
480480
store_failures_as: Optional[str] = None
481481
where: Optional[str] = None
@@ -1132,7 +1132,7 @@ class Config14(BaseParserModel):
11321132
meta: Optional[dict[str, Any]] = None
11331133
group: Optional[str] = None
11341134
materialized: Optional[str] = "test"
1135-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
1135+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
11361136
store_failures: Optional[bool] = None
11371137
store_failures_as: Optional[str] = None
11381138
where: Optional[str] = None
@@ -2386,7 +2386,7 @@ class Config29(BaseParserModel):
23862386
meta: Optional[dict[str, Any]] = None
23872387
group: Optional[str] = None
23882388
materialized: Optional[str] = "test"
2389-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
2389+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
23902390
store_failures: Optional[bool] = None
23912391
store_failures_as: Optional[str] = None
23922392
where: Optional[str] = None
@@ -3016,7 +3016,7 @@ class Config38(BaseParserModel):
30163016
meta: Optional[dict[str, Any]] = None
30173017
group: Optional[str] = None
30183018
materialized: Optional[str] = "test"
3019-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
3019+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
30203020
store_failures: Optional[bool] = None
30213021
store_failures_as: Optional[str] = None
30223022
where: Optional[str] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -26,7 +26,7 @@ class ManifestMetadata(BaseParserModel):
2626
invocation_id: Optional[str] = None
2727
env: Optional[dict[str, str]] = {}
2828
project_id: Optional[str] = Field(None, description="A unique identifier for the project")
29-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
29+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3030
None, description="A unique identifier for the user"
3131
)
3232
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -110,7 +110,7 @@ class TestConfig(BaseParserModel):
110110
database: Optional[str] = None
111111
tags: Optional[Union[list[str], str]] = []
112112
full_refresh: Optional[bool] = None
113-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
113+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
114114
store_failures: Optional[bool] = None
115115
where: Optional[str] = None
116116
limit: Optional[int] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v3.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -26,7 +26,7 @@ class ManifestMetadata(BaseParserModel):
2626
invocation_id: Optional[str] = None
2727
env: Optional[dict[str, str]] = {}
2828
project_id: Optional[str] = Field(None, description="A unique identifier for the project")
29-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
29+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3030
None, description="A unique identifier for the user"
3131
)
3232
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -104,7 +104,7 @@ class TestConfig(BaseParserModel):
104104
tags: Optional[Union[list[str], str]] = []
105105
meta: Optional[dict[str, Any]] = {}
106106
materialized: Optional[str] = "test"
107-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
107+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
108108
store_failures: Optional[bool] = None
109109
where: Optional[str] = None
110110
limit: Optional[int] = None

0 commit comments

Comments
 (0)