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-settings explicitly; v2’s pydantic no longer bundles BaseSettings.
  • Field(env="X") is replaced by validation_alias / AliasChoices in v2.
  • v2 keeps lenient env-string coercion, so "false" still parses to False for bool fields.
  • Run with -W error to surface deprecation warnings the upgrade introduces.

Production parity checklist

  • pydantic-settings is a pinned dependency.
  • All Config classes replaced with SettingsConfigDict.
  • Validators renamed to field_validator/model_validator.
  • .dict()/.parse_obj() replaced with model_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.