Использование Flask для переноса данных на основе запроса [duplicate]

Я считаю, что наилучшей практикой должно быть пройти официальный Java JSON API , который все еще работает.

41
задан davidism 8 July 2014 в 04:36
поделиться

1 ответ

То, что вы запрашиваете, - это миграция данных , в отличие от миграции схемы , которая наиболее распространена в документах Alembic.

ответ предполагает, что вы используете декларативные (в отличие от класса-Mapper-Table или core), чтобы определить ваши модели. Это должно быть относительно просто адаптировать это к другим формам.

Обратите внимание, что Alembic предоставляет некоторые основные функции данных: 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')

Миграция определяет отдельные модели, поскольку модели в ваш код представляет текущее состояние базы данных, а миграции представляют шаги по пути . Ваша база данных может находиться в любом состоянии по этому пути, поэтому модели могут не синхронизироваться с базой данных. Если вы не очень осторожны, использование реальных моделей напрямую вызовет проблемы с отсутствующими столбцами, недопустимыми данными и т. Д. Яснее четко указать, какие столбцы и модели вы будете использовать в процессе миграции.

73
ответ дан davidism 24 August 2018 в 16:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: