from pydantic import BaseSettings fails on Pydantic v2 with an error telling you that BaseSettings has moved. It now lives in the pydantic-settings distribution and is imported as from pydantic_settings import BaseSettings. Several extra types moved likewise into pydantic-extra-types.
The configuration surface changed with the move. class Config: env_prefix = ... becomes model_config = SettingsConfigDict(env_prefix=..., env_file=".env"), and SettingsConfigDict rather than plain ConfigDict is required to get the settings-specific keys.
One behavioural difference bites during migration: nested models are populated from environment variables using a delimiter that is empty by default, so DATABASE__HOST only maps into a nested database.host once you set env_nested_delimiter="__". Complex fields such as lists and dicts are parsed as JSON from the environment, so a list must be written as a JSON array in the variable value rather than as a comma-separated string, unless you add a validator that splits it.