Error [BaseSettings` has been moved to the `pydantic-settings` package]

PydanticImportError: `BaseSettings` has been moved to the `pydantic-settings` package の直し方(Pydantic 2 で BaseSettings が別パッケージへ移った)

FIX SUMMARY verified
Applies when
python:3.12.12-slimPydantic 2 (BaseSettings moved to the pydantic-settings package)from pydantic import BaseSettings on Pydantic 2 (own code, or via a fresh FastAPI install that pulls Pydantic 2 but not pydantic-settings)

Verified: reproduced in python:3.12.12-slim, then the BaseSettings` has been moved to the `pydantic-settings` package signature was gone after the fix (exit 0).

設定クラスを読み込む from pydantic import BaseSettings の行で、次のエラーが出て止まることがあります。

pydantic.errors.PydanticImportError: `BaseSettings` has been moved to the `pydantic-settings` package. See https://docs.pydantic.dev/2.9/migration/#basesettings-has-moved-to-pydantic-settings for more details.

For further information visit https://errors.pydantic.dev/2.9/u/import-error

例外クラスは PydanticImportError、末尾に errors.pydantic.dev/.../u/import-error の URL が付く形で出ます。原因は、Pydantic 2 で BaseSettings が本体から pydantic-settings という別パッケージへ移されたことです。直すのは、パッケージを1つ足して import 元を1行変えるだけです。

pip install pydantic-settings
# 変更前
from pydantic import BaseSettings
# 変更後
from pydantic_settings import BaseSettings

なぜ起きるのか:BaseSettings は本体から出て別パッケージになった

BaseSettings は、環境変数や .env から設定を読み込むためのクラスです。Pydantic 1 では本体(pydantic)に入っていて、from pydantic import BaseSettings で取れました。Pydantic 2 では、この設定管理の機能が本体から切り離され、pydantic-settings という独立したパッケージへ移りました

そのため Pydantic 2 の本体には BaseSettings という名前がありません。from pydantic import BaseSettings を書くと、Pydantic はそれが移動済みの名前だと知っていて、PydanticImportError を投げて移動先を案内します。エラー文にそのまま pydantic-settings パッケージ名と移行ガイドの URL が入っているのはそのためです。名前が消えたのではなく、取り出す場所が変わっただけなので、pydantic-settings を入れて from pydantic_settings import BaseSettings にすれば、同じクラスがそのまま使えます

なぜ Pydantic 2 で出るのか

このエラーの引き金は Pydantic のメジャーバージョンです。Pydantic 1(例:1.10 系)では from pydantic import BaseSettings が通ります。Pydantic 2 に上げた後だけ、同じ import が PydanticImportError になります。手元の環境やこれまでの requirements.txt が Pydantic 1 のままなら踏みません。次のような場面で表面化します。

  • Pydantic を 1 系から 2 系へ上げたpip install --upgrade pydantic や、版を固定していない環境を作り直したときに 2 系が入り、設定クラスの import だけが落ちる。
  • FastAPI をきっかけに 2 系が入った:FastAPI は Pydantic 2 の上で動くので、新しく pip install fastapi すると Pydantic 2 が一緒に入ります。ところが pip install fastapipydantic-settings までは入れません(後述)。FastAPI のチュートリアルは設定管理に BaseSettings を使うため、その通りに書いたのに import で落ちる、という組み合わせになります。
  • 手元は 1 系のまま、CI やコンテナだけ 2 系:ビルドイメージや lock ファイルの版が食い違い、片方だけ落ちる。

まず pip show pydantic pydantic-settings で、Pydantic が 2 系かどうかと、pydantic-settings が入っているかを確かめます。

FastAPI を入れても pydantic-settings は入らない

FastAPI 経由でこのエラーに当たる場合、依存の引き方に理由があります。pip install fastapi が依存として引くのは Pydantic 本体(2 系)で、エクストラを付けない素の pip install fastapipydantic-settings を引きませんpydantic-settingsfastapi[standard](現在の公式推奨インストール)や fastapi[all] のエクストラに入っています。つまりエクストラ無しでインストールを終えた直後の状態は、BaseSettings が本体に無い Pydantic 2 が入っていて、その移動先である pydantic-settings は入っていない、という噛み合わせになります。設定クラスを書いた瞬間に import で止まるのはこのためです。pydantic-settings は自分で明示的に入れます。

直し方1:pydantic-settings を入れて import 元を変える

自分のコードで BaseSettings を使っているなら、これが本筋です。パッケージを足して、import 元を pydantic_settings に変えます。

pip install pydantic-settings
# 変更前
from pydantic import BaseSettings

# 変更後
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    app_name: str = "errfix"

requirements.txtpyproject.toml を使っているなら、pydantic-settings を依存に書き足します。書いておかないと、環境を作り直したときに再び入らず、同じ import エラーに戻ります。FastAPI のプロジェクトでも同様で、fastapi と並べて pydantic-settings を明示します。

FieldBaseModel など、from pydantic import ... で取っていた他の名前は本体に残っているので、そのままで動きます。移すのは BaseSettings(および pydantic-settings にまとめられた設定関連のクラス)の import 元だけです。

直し方2:まだ Pydantic 2 に移れないとき、つなぎで 1 系に留める

コード全体が Pydantic 1 の書き方(class Config での設定、.dict()、旧いバリデータなど)に依存していて、いま 2 系へ移す余裕がない場合は、当座は Pydantic を 1 系に固定して from pydantic import BaseSettings を生かす手があります。

pip install "pydantic<2"

これは 2 系への移行を先送りする暫定策です。Pydantic 1 系は保守中心の版で、新機能や新しいエコシステムの前提は 2 系に寄っていきます。requirements.txt に固定するなら、なぜ 1 系に留めているか(2 系への移行が済むまでの暫定である旨)をコメントで添えて、移行後に外せるようにしておきます。恒久的にこの版へ張り付けるのではなく、pydantic-settings を使う直し方1へ移すのが後を引きません。

FastAPI と併用しているなら、この固定の前に FastAPI の版を確認します。 FastAPI が受け付ける Pydantic の版は、FastAPI 自身の版で変わります。FastAPI 0.125 以前は Pydantic 1(1.7.4 以上)と 2 の両方を受け付けるので、その版なら pydantic<2 固定でも FastAPI は壊れません。一方 FastAPI 0.126 以降は Pydantic 2 のみ(現行の 0.139 は pydantic>=2.9)で、pydantic<2 を入れると FastAPI の依存要求と衝突するか、FastAPI 側が古い版へ引き下げられます。現行の FastAPI を使っているなら pydantic<2 は選べません——その場合は直し方1(pydantic-settings を入れて import を移す)だけが道です。この BaseSettings エラーを踏む人の多くは、すでに Pydantic 2 が入っている=新しい FastAPI 側にいるので、実際には直し方1が本筋になります。

切り分け(うまくいかないとき)

  • import は直ったのに、今度は class Config の警告や SettingsConfigDict 絡みのエラーが出るBaseSettings を継承したクラスの中で内側の class Configenv_file などを書いていた場合、Pydantic 2 ではその書き方が非推奨です。設定は model_config = SettingsConfigDict(env_file=".env") の形に移します(from pydantic_settings import SettingsConfigDict)。import の移動と、この設定 API の変更は別の変更なので、順に対応します。
  • BaseSettings 以外の名前でも似た PydanticImportError が出る:Pydantic 2 で本体から移動・変更された名前を 1 系の場所から読むと、同型のエラーになります。エラー文がそのまま移動先を案内するので、案内された import 元に合わせます。移行全体の対応表は Pydantic 公式の移行ガイド(エラー文中の URL)にあります。
  • pip install fastapi は通ったのに、起動時に設定クラスで落ちる:FastAPI は pydantic-settings を素の依存に含めません(all エクストラのみ)。pip install pydantic-settings を追加します。
  • pip install pydantic-settings したのに、まだ本体から import している箇所が残って落ちるfrom pydantic import BaseSettings をコード全体で検索し、from pydantic_settings import BaseSettings に置き換えます。第三者ライブラリの中で古い import が残っている場合は、そのライブラリを Pydantic 2 対応版へ上げます。
  • 同じ「版を上げたら import が落ちた」でも、名前ごと消えている場合:Flask で from werkzeug.urls import url_quote が落ちる型は、移動ではなく削除で、対処は版の固定か Flask 側の更新になります(url_quote の ImportError の直し方)。Pydantic の BaseSettings は移動先が明示されているぶん、パッケージを足せば元のコードをそのまま使えます。

検証環境

  • python:3.12.12-slim、ネットワーク有り
  • 再現:pip install "pydantic==2.9.2" の後、from pydantic import BaseSettings を含むスクリプトが PydanticImportError: BaseSettingshas been moved to thepydantic-settings package で終了コード 1
  • 修正:pip install "pydantic==2.9.2" "pydantic-settings==2.6.1" の後、from pydantic_settings import BaseSettings に変えた同じスクリプトが終了コード 0

再現から修正までは errfix の検証ハーネスが機械的に確認しています。版境界は、pydantic==1.10.18 では from pydantic import BaseSettings が終了コード 0 で通ることを別途実測して裏づけました(Pydantic 1 では本体に BaseSettings がある)。エクストラを付けない pip install fastapi が Pydantic 2 系を引く一方で pydantic-settings を引かないこと、pydantic-settingsfastapi[standard] / fastapi[all] のエクストラに含まれること、および現行 FastAPI(0.139)が pydantic>=2.9 を要求する(Pydantic 1 を受け付けない)ことは、PyPI のパッケージメタデータ(requires_dist)とインストール後の構成で確認しています。移動の経緯や設定 API(class ConfigSettingsConfigDict)の変更は、Pydantic 公式の移行ガイドに沿って書いています。エラー文言は実機出力から引用しました。

検証(machine-verified)

この修正は python:3.12.12-slim のバージョン固定コンテナ内で再現し、修正後に BaseSettings` has been moved to the `pydantic-settings` package のシグネチャが消えることを機械で確認しています。

verify — run-case.mjs
$ node run-case.mjs python/pydantic-basesettings-moved
● reproduce BaseSettings` has been moved to the `pydantic-settings` package present ✓
● apply fix exit 0
● re-run BaseSettings` has been moved to the `pydantic-settings` package gone ✓
PASS verified · python:3.12.12-slim · signature gone

確認したのは上のイメージの中だけです。別の環境で直らなかった、記述が違う、という場合は 報告してください(対象と検証イメージは件名・本文に入ります)。