reconoce que pip3 orden modulos interno instalar externo encontró como comando agregar actualizar python sqlalchemy alembic

python - que - ¿Cómo ejecuto inserciones y actualizaciones en un script de actualización de Alembic?



pip3 no se reconoce como un comando interno o externo (1)

Necesito alterar los datos durante una actualización de Alembic.

Actualmente tengo una mesa de ''jugadores'' en una primera revisión:

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'') )

Quiero introducir una mesa de ''equipos''. He creado una segunda revisión:

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))

Me gustaría que la segunda migración también agregue los siguientes datos:

  1. Tabla de equipos de población:

    INSERT INTO teams (name) SELECT DISTINCT team FROM players;

  2. Actualice players.team_id basado en players.team name:

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

¿Cómo ejecuto inserciones y actualizaciones dentro del script de actualización?


Lo que solicita es una migración de datos , a diferencia de la migración de esquemas que prevalece en los documentos de Alembic.

Esta respuesta asume que está utilizando declarativo (en lugar de class-Mapper-Table o core) para definir sus modelos. Debería ser relativamente sencillo adaptar esto a las otras formas.

Tenga en cuenta que Alembic proporciona algunas funciones básicas de datos: op.bulk_insert() y op.execute() . Si las operaciones son mínimas, úsalas. Si la migración requiere relaciones u otras interacciones complejas, prefiero usar todo el poder de los modelos y sesiones como se describe a continuación.

El siguiente es un ejemplo de script de migración que configura algunos modelos declarativos que se utilizarán para manipular los datos en una sesión. Los puntos clave son:

  1. Defina los modelos básicos que necesita, con las columnas que necesitará. No necesita cada columna, solo la clave principal y las que usará.
  2. Dentro de la función de actualización, use op.get_bind() para obtener la conexión actual, y haga una sesión con ella.

    • O use bind.execute() para usar el nivel inferior de SQLAlchemy para escribir consultas SQL directamente. Esto es útil para migraciones simples.
  3. Use los modelos y la sesión como lo haría normalmente en su aplicación.

"""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'')

La migración define modelos separados porque los modelos en su código representan el estado actual de la base de datos, mientras que las migraciones representan pasos en el camino . Su base de datos podría estar en cualquier estado a lo largo de esa ruta, por lo que los modelos podrían no estar sincronizados con la base de datos todavía. A menos que tenga mucho cuidado, el uso directo de modelos reales causará problemas con columnas faltantes, datos no válidos, etc. Es más claro que se establezca explícitamente qué columnas y modelos utilizará en la migración.