Alembicアップグレードスクリプトで挿入と更新を実行するにはどうすればよいですか?

Arek S:

Alembicのアップグレード中にデータを変更する必要があります。

私は現在、最初のリビジョンに「プレーヤー」テーブルがあります:

def upgrade():
    op.create_table('player',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('name', sa.Unicode(length=200), nullable=False),
        sa.Column('position', sa.Unicode(length=200), nullable=True),
        sa.Column('team', sa.Unicode(length=100), nullable=True)
        sa.PrimaryKeyConstraint('id')
    )

「チーム」テーブルを紹介したいと思います。2つ目のリビジョンを作成しました。

def upgrade():
    op.create_table('teams',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('name', sa.String(length=80), nullable=False)
    )
    op.add_column('players', sa.Column('team_id', sa.Integer(), nullable=False))

2回目の移行で次のデータも追加してください。

  1. チームテーブルに入力します。

    INSERT INTO teams (name) SELECT DISTINCT team FROM players;
    
  2. players.teamの名前に基づいて、players.team_idを更新します。

    UPDATE players AS p JOIN teams AS t SET p.team_id = t.id WHERE p.team = t.name;
    

アップグレードスクリプト内で挿入と更新を実行するにはどうすればよいですか?

ダビディズム:

Alembicのドキュメントで最も一般的なスキーマの移行とは対照的に、求めているのはデータの移行です。

この回答は、モデルを定義するために(class-Mapper-Tableまたはコアではなく)宣言型を使用していることを前提としています。これを他の形式に合わせるのは比較的簡単なはずです。

アレンビックは、いくつかの基本的なデータ機能を提供することに注意してください:op.bulk_insert()op.execute()操作がかなり最小限の場合は、それらを使用してください。移行で関係やその他の複雑な相互作用が必要な場合は、以下で説明するように、モデルとセッションの全機能を使用することを好みます。

以下は、セッションでデータを操作するために使用されるいくつかの宣言モデルを設定する移行スクリプトの例です。重要な点は次のとおりです。

  1. 必要な列を使用して、必要な基本モデルを定義します。すべての列が必要なわけではなく、主キーと使用する列だけが必要です。

  2. アップグレード関数内で、を使用op.get_bind()して現在の接続を取得し、それを使用してセッションを確立します。

    • または、bind.execute()SQLAlchemyの下位レベルを使用してSQLクエリを直接書き込むために使用します。これは単純な移行に役立ちます。
  3. アプリケーションで通常行うようにモデルとセッションを使用します。

"""create teams table

Revision ID: 169ad57156f0
Revises: 29b4c2bfce6d
Create Date: 2014-06-25 09:00:06.784170
"""

revision = '169ad57156f0'
down_revision = '29b4c2bfce6d'

from alembic import op
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class Player(Base):
    __tablename__ = 'players'

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String, nullable=False)
    team_name = sa.Column('team', sa.String, nullable=False)
    team_id = sa.Column(sa.Integer, sa.ForeignKey('teams.id'), nullable=False)

    team = orm.relationship('Team', backref='players')


class Team(Base):
    __tablename__ = 'teams'

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String, nullable=False, unique=True)


def upgrade():
    bind = op.get_bind()
    session = orm.Session(bind=bind)

    # create the teams table and the players.team_id column
    Team.__table__.create(bind)
    op.add_column('players', sa.Column('team_id', sa.ForeignKey('teams.id'), nullable=False)

    # create teams for each team name
    teams = {name: Team(name=name) for name in session.query(Player.team).distinct()}
    session.add_all(teams.values())

    # set player team based on team name
    for player in session.query(Player):
        player.team = teams[player.team_name]

    session.commit()

    # don't need team name now that team relationship is set
    op.drop_column('players', 'team')


def downgrade():
    bind = op.get_bind()
    session = orm.Session(bind=bind)

    # re-add the players.team column
    op.add_column('players', sa.Column('team', sa.String, nullable=False)

    # set players.team based on team relationship
    for player in session.query(Player):
        player.team_name = player.team.name

    session.commit()

    op.drop_column('players', 'team_id')
    op.drop_table('teams')

コード内のモデルはデータベースの現在の状態表すので、移行は別のモデルを定義しますが、移行はその途中のステップを表しますデータベースはそのパスに沿った任意の状態にある可能性があるため、モデルはまだデータベースと同期していない可能性があります。細心の注意を払わない限り、実際のモデルを直接使用すると、列の欠落、無効なデータなどの問題が発生します。移行で使用する列とモデルを正確に明示する方が明確です。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ウィザードのアクティブなステップでSQL挿入を実行するにはどうすればよいですか?

分類Dev

AWSでバックグラウンドサービスとしてPHPスクリプトを実行するにはどうすればよいですか?

分類Dev

node.jsアプリをバックグラウンドサービスとして実行するにはどうすればよいですか?

分類Dev

クリップボードに行をコピーしたときにExcelに空の行を挿入するにはどうすればよいですか?

分類Dev

デスクトップアプリでナイトモードでSlackを実行するにはどうすればよいですか?

分類Dev

Spring MVC Webアプリでほとんどのリクエストに共通のコードを実行するにはどうすればよいですか?

分類Dev

Webスクレイピングにバックオフスクリプトを挿入するにはどうすればよいですか

分類Dev

変換を使用せずにssisでSQLタスクの実行からレコードを挿入、更新するにはどうすればよいですか?

分類Dev

アップルストアでiOSフラッターアプリをアップグレードするにはどうすればよいですか?

分類Dev

リストの挿入とポップを一度に実行するにはどうすればよいですか?

分類Dev

アプリがバックグラウンドモードのときに関数を実行するにはどうすればよいですか?

分類Dev

スクリプトタグに文字列を挿入するにはどうすればよいですか?

分類Dev

別のスレッドから現在のASP.NetaspxページでJSスクリプトを実行するにはどうすればよいですか?

分類Dev

Magento:インストール/アップグレードスクリプトを使用して属性を追加するにはどうすればよいですか?

分類Dev

リリースアップグレードを再開するにはどうすればよいですか?

分類Dev

リリースアップグレードを再開するにはどうすればよいですか?

分類Dev

ボタンを使用してページにアプレットをアクセス可能に挿入するにはどうすればよいですか?

分類Dev

タッチダイアログをテストして実際のアプリ内購入を実行するにはどうすればよいですか?

分類Dev

(python)スクリプトをjenkinsにアップロードして実行するにはどうすればよいですか?

分類Dev

AzureFunctionアプリでPnPスクリプトを実行するにはどうすればよいですか

分類Dev

gulpで挿入されたスクリプトパスのパスプレフィックスを削除するにはどうすればよいですか?

分類Dev

C#WindowsアプリケーションでデータグリッドビューエントリからSQLデータベースにレコードを挿入するにはどうすればよいですか?

分類Dev

更新せずにjspスクリプトレットを実行する検索ボタンを作成するにはどうすればよいですか?

分類Dev

既存のGoogleワークシートをGoogleスプレッドシートに挿入するにはどうすればよいですか?

分類Dev

ネットワークの中断後にリリースアップグレードを再開するにはどうすればよいですか?

分類Dev

実行中のキオスクモードのChromeアプリケーションをデバッグするにはどうすればよいですか?

分類Dev

最初にディレクトリにCDを挿入せずに、1つのコマンドで長いパスに存在するシェルスクリプトを実行するにはどうすればよいですか?

分類Dev

ORMLightアップグレードデータベース自動インクリメントを削除して新しいforeigncollectionを挿入するにはどうすればよいですか

分類Dev

Excelスプレッドシートの欠落している行に空白のエントリを挿入するにはどうすればよいですか(リファレンスシートと比較して)?

Related 関連記事

  1. 1

    ウィザードのアクティブなステップでSQL挿入を実行するにはどうすればよいですか?

  2. 2

    AWSでバックグラウンドサービスとしてPHPスクリプトを実行するにはどうすればよいですか?

  3. 3

    node.jsアプリをバックグラウンドサービスとして実行するにはどうすればよいですか?

  4. 4

    クリップボードに行をコピーしたときにExcelに空の行を挿入するにはどうすればよいですか?

  5. 5

    デスクトップアプリでナイトモードでSlackを実行するにはどうすればよいですか?

  6. 6

    Spring MVC Webアプリでほとんどのリクエストに共通のコードを実行するにはどうすればよいですか?

  7. 7

    Webスクレイピングにバックオフスクリプトを挿入するにはどうすればよいですか

  8. 8

    変換を使用せずにssisでSQLタスクの実行からレコードを挿入、更新するにはどうすればよいですか?

  9. 9

    アップルストアでiOSフラッターアプリをアップグレードするにはどうすればよいですか?

  10. 10

    リストの挿入とポップを一度に実行するにはどうすればよいですか?

  11. 11

    アプリがバックグラウンドモードのときに関数を実行するにはどうすればよいですか?

  12. 12

    スクリプトタグに文字列を挿入するにはどうすればよいですか?

  13. 13

    別のスレッドから現在のASP.NetaspxページでJSスクリプトを実行するにはどうすればよいですか?

  14. 14

    Magento:インストール/アップグレードスクリプトを使用して属性を追加するにはどうすればよいですか?

  15. 15

    リリースアップグレードを再開するにはどうすればよいですか?

  16. 16

    リリースアップグレードを再開するにはどうすればよいですか?

  17. 17

    ボタンを使用してページにアプレットをアクセス可能に挿入するにはどうすればよいですか?

  18. 18

    タッチダイアログをテストして実際のアプリ内購入を実行するにはどうすればよいですか?

  19. 19

    (python)スクリプトをjenkinsにアップロードして実行するにはどうすればよいですか?

  20. 20

    AzureFunctionアプリでPnPスクリプトを実行するにはどうすればよいですか

  21. 21

    gulpで挿入されたスクリプトパスのパスプレフィックスを削除するにはどうすればよいですか?

  22. 22

    C#WindowsアプリケーションでデータグリッドビューエントリからSQLデータベースにレコードを挿入するにはどうすればよいですか?

  23. 23

    更新せずにjspスクリプトレットを実行する検索ボタンを作成するにはどうすればよいですか?

  24. 24

    既存のGoogleワークシートをGoogleスプレッドシートに挿入するにはどうすればよいですか?

  25. 25

    ネットワークの中断後にリリースアップグレードを再開するにはどうすればよいですか?

  26. 26

    実行中のキオスクモードのChromeアプリケーションをデバッグするにはどうすればよいですか?

  27. 27

    最初にディレクトリにCDを挿入せずに、1つのコマンドで長いパスに存在するシェルスクリプトを実行するにはどうすればよいですか?

  28. 28

    ORMLightアップグレードデータベース自動インクリメントを削除して新しいforeigncollectionを挿入するにはどうすればよいですか

  29. 29

    Excelスプレッドシートの欠落している行に空白のエントリを挿入するにはどうすればよいですか(リファレンスシートと比較して)?

ホットタグ

アーカイブ