web-dev-qa-db-ja.com

sqlalchemyを使用して頻繁なスキーマ変更を効率的に管理するにはどうすればよいですか?

私はsqlalchemyを使用してWebアプリケーションをプログラミングしています。サイトが稼働していない開発の最初のフェーズでは、すべてがスムーズでした。古いsqliteデータベースを削除して新しいデータベースを最初から作成するだけで、データベーススキーマを簡単に変更できました。

現在、サイトは運用中であり、データを保持する必要がありますが、データベースを新しいスキーマに簡単に変換することで、元の開発速度を維持したいと考えています。

データベースのスキーマを説明するリビジョン50のmodel.pyとリビジョン75のmodel.pyがあるとします。これらの2つのスキーマ間では、ほとんどの変更は簡単です。たとえば、新しい列がデフォルト値で宣言されており、このデフォルト値を古いレコードに追加したいだけです。

最終的に、いくつかの変更は簡単ではなく、事前の計算が必要になる場合があります。

たとえば、1日に1つまたは2つの新しいバージョンの量産コードを使用して、急速に変化するWebアプリケーションをどのように処理しますか(または処理しますか)。

ちなみに、サイトがPylonsで書かれている場合は、違いが見られます。

52
ascobol

Alembic は、SQLAlchemyの作成者が記述した新しいデータベース移行ツールです。 sqlalchemy-migrateよりもはるかに使いやすいことがわかりました。また、Flask-SQLAlchemyとシームレスに連携します。

SQLAlchemyモデルからスキーマ移行スクリプトを自動生成します。

alembic revision --autogenerate -m "description of changes"

次に、新しいスキーマの変更をデータベースに適用します。

alembic upgrade head

詳細はこちら: http://readthedocs.org/docs/alembic/

36
Alan Hamlett

私達がすること。

  1. アプリケーションの「メジャーバージョン」。「マイナーバージョン」識別を使用します。メジャーバージョンはスキーマのバージョン番号です。メジャー番号は、ランダムな「十分な新機能」のようなものではありません。これは、データベーススキーマとの互換性を正式に宣言したものです。

    リリース2.3と2.4はどちらもスキーマバージョン2を使用します。

    リリース3.1はバージョン3スキーマを使用します。

  2. スキーマのバージョンを非常にわかりやすくします。 SQLiteの場合、これはデータベースファイル名にスキーマバージョン番号を保持することを意味します。 MySQLの場合、データベース名を使用します。

  3. 移行スクリプトを記述します。 2to3.py、3to4.py。これらのスクリプトは2つのフェーズで機能します。 (1)古いデータを新しい構造にクエリして、シンプルなCSVまたはJSONファイルを作成します。 (2)単純なCSVファイルまたはJSONファイルから、それ以上の処理を行わずに新しい構造をロードします。これらの抽出ファイル-適切な構造になっているため、読み込みが速く、単体テストのフィクスチャとして簡単に使用できます。また、2つのデータベースを同時に開くことはできません。これにより、スクリプトが少し単純になります。最後に、ロードファイルを使用して、データを別のデータベースサーバーに移動できます。

スキーマの移行を「自動化」することは非常に困難です。自動化されたスクリプトでは、古いスキーマから新しいスキーマにデータを簡単にマップできないほど、データベースの手術を非常に深くするのは簡単です(そして一般的です)。

14
S.Lott

sqlalchemy-migrate を使用します。

スキーマの変更が必要なため、データベース設計へのアジャイルアプローチをサポートし、開発データベースと本番データベースの同期を維持しやすくするように設計されています。スキーマのバージョン管理が簡単になります。

データベーススキーマのバージョン管理と考えてください。各スキーマの変更をコミットすると、スキーマのバージョンを前方/後方に移動できます。このようにしてクライアントをアップグレードすると、クライアントのデータベースに適用する変更のセットが正確にわかります。

それはS.Lottが彼の答えで提案することを、あなたのために自動的に行います。難しいことを簡単にします。

13
nosklo

問題に対処する最良の方法は、宣言的な方法でスキーマを反映することです。私はここでリフレクティブアプローチについての記事を書きました: http://petrushev.wordpress.com/2010/06/16/reflective-approach-on-sqlalchemy-usage/ これに関する他のリソースがありますまた。このようにして、スキーマに変更を加えるたびに、アプリを再起動するだけで、リフレクションがテーブルの変更の新しいメタデータをフェッチします。これは非常に高速で、sqlalchemyはプロセスごとに1回だけ実行します。もちろん、自分で行った関係の変更を管理する必要があります。

1
vonPetrushev