Pydantic v1 to v2 settings migration
Upgrading pydantic to v2 moves BaseSettings to a new package, replaces the inner Config class, and renames the validator decorators. Miss one and the app raises at import. This page is the field-by-field migration, extending Pydantic Settings Fundamentals.
Problem 1: the import moved
# ANTI-PATTERN (v1): BaseSettings no longer lives in pydantic
from pydantic import BaseSettings # ImportError under pydantic v2
In v2, BaseSettings moved to the separate pydantic-settings package.
Problem 2: v1 Config and validators
# ANTI-PATTERN (v1): inner Config + @validator
class Settings(BaseSettings):
class Config: # -> SettingsConfigDict
env_file = ".env"
@validator("port") # -> @field_validator + @classmethod
def check(cls, v): ...
The inner Config class and @validator are gone in v2.
Secure implementation
# config/settings.py — v2
from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict # new package
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="forbid") # replaces Config
port: int = 8080
@field_validator("port") # replaces @validator
@classmethod
def check(cls, v: int) -> int:
if not 1 <= v <= 65535:
raise ValueError("port out of range")
return v
Migration map
| pydantic v1 | pydantic v2 |
|---|---|
from pydantic import BaseSettings |
from pydantic_settings import BaseSettings |
inner class Config |
model_config = SettingsConfigDict(...) |
@validator |
@field_validator + @classmethod |
@root_validator |
@model_validator |
.dict() / .json() |
.model_dump() / .model_dump_json() |
.parse_obj() |
.model_validate() |
Gotchas & version-specific behaviour
- Install
pydantic-settingsexplicitly; v2’spydanticno longer bundlesBaseSettings. Field(env="X")is replaced byvalidation_alias/AliasChoicesin v2.- v2 keeps lenient env-string coercion, so
"false"still parses toFalsefor bool fields. - Run with
-W errorto surface deprecation warnings the upgrade introduces.
Production parity checklist
pydantic-settingsis a pinned dependency.- All
Configclasses replaced withSettingsConfigDict. - Validators renamed to
field_validator/model_validator. .dict()/.parse_obj()replaced withmodel_dump/model_validate.- A parity test compares v2 output against the v1 baseline before cutover.
Conclusion
Move the import, swap Config for SettingsConfigDict, rename the validators, and update the dump/parse calls — then verify parity before deleting v1 code. For migrating off a non-pydantic parser entirely, see Migrate to pydantic-settings v2.