Ich habe versucht, alembic auszuführen, ein Migrationstool für Python

Ziel

Versuchen Sie, das Python-Migrationspaket [alembic · PyPI] auszuführen (https://pypi.org/project/alembic/).

Was ist Destillierkolben? ??

Ein Migrationstool, das Ihre Datenbank verwaltet, wenn Sie SQLAlchemy mit Python verwenden

Umweltvorbereitung

Erstellen Sie mit Docker eine Umgebung

Ich möchte es einfach erstellen, also werde ich es mit Docker machen

Ordnerstruktur


.
├── README.md
├── docker-compose.yml
└── src
    └── model.py

docker-compose.yml


version: "3"

services:
  db:
    image: postgres:11.7
    container_name: alembic-db
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=almebic
  app:
    image: python:3.8.2-slim
    container_name: alembic-app
    volumes:
      - ./src:/usr/src
    environment:
      - PYTHONPATH=${PYTHONPATH}:/usr/src
    tty: true

Installieren Sie Alembic

Installieren Sie die erforderlichen Pakete mit pip

pip install alembic psycopg2-binary

Wenn Sie alembic installieren, wird gleichzeitig ** SQLAlchemy ** installiert. ** psycopg2-binary · PyPI ** wird verwendet, um eine Verbindung zu Postgres herzustellen

alembic Installation


root@9a7582105665:/usr/src# pip install alembic psycopg2-binary
Collecting alembic
  Downloading alembic-1.4.2.tar.gz (1.1 MB)
     |████████████████████████████████| 1.1 MB 7.8 MB/s
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Collecting psycopg2-binary
  Downloading psycopg2_binary-2.8.5-cp38-cp38-manylinux1_x86_64.whl (3.0 MB)
     |████████████████████████████████| 3.0 MB 32.3 MB/s
Collecting python-dateutil
  Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
     |████████████████████████████████| 227 kB 23.8 MB/s
Collecting Mako
  Downloading Mako-1.1.2-py2.py3-none-any.whl (75 kB)
     |████████████████████████████████| 75 kB 11.2 MB/s
Collecting SQLAlchemy>=1.1.0
  Downloading SQLAlchemy-1.3.16-cp38-cp38-manylinux2010_x86_64.whl (1.2 MB)
     |████████████████████████████████| 1.2 MB 54.3 MB/s
Collecting python-editor>=0.3
  Downloading python_editor-1.0.4-py3-none-any.whl (4.9 kB)
Collecting six>=1.5
  Downloading six-1.14.0-py2.py3-none-any.whl (10 kB)
Collecting MarkupSafe>=0.9.2
  Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
Building wheels for collected packages: alembic
  Building wheel for alembic (PEP 517) ... done
  Created wheel for alembic: filename=alembic-1.4.2-py2.py3-none-any.whl size=159543 sha256=dc29f47f6c24908d9413da7e3c969c64c252d0cbf9f90fca7cfbb5782b2452d0
  Stored in directory: /root/.cache/pip/wheels/70/08/70/cea787a7e95817b831469fa42af076046e55a05f7c94657463
Successfully built alembic
Installing collected packages: six, python-dateutil, MarkupSafe, Mako, SQLAlchemy, python-editor, alembic, psycopg2-binary
Successfully installed Mako-1.1.2 MarkupSafe-1.1.1 SQLAlchemy-1.3.16 alembic-1.4.2 psycopg2-binary-2.8.5 python-dateutil-2.8.1 python-editor-1.0.4 six-1.14.0

Überprüfen Sie die Paketversion


root@ecce2b20848e:/usr/src# pip list
Package         Version
--------------- -------
alembic         1.4.2
Mako            1.1.2
MarkupSafe      1.1.1
pip             20.1
psycopg2-binary 2.8.5
python-dateutil 2.8.1
python-editor   1.0.4
setuptools      46.1.3
six             1.14.0
SQLAlchemy      1.3.16
wheel           0.34.2

Erstellen Sie eine alembische Umgebung

Erstellen einer Migrationsumgebung mit alembic init

alembic init {Name der Migrationsumgebung}

Erstellen Sie eine Migrationsumgebung mit

Grundeinstellung des Destillierkolbens


root@ecce2b20848e:/usr/src# alembic init migration
  Creating directory /usr/src/migration ...  done
  Creating directory /usr/src/migration/versions ...  done
  Generating /usr/src/migration/README ...  done
  Generating /usr/src/alembic.ini ...  done
  Generating /usr/src/migration/env.py ...  done
  Generating /usr/src/migration/script.py.mako ...  done
  Please edit configuration/connection/logging settings in '/usr/src/alembic.ini' before proceeding.

Wenn die Erstellung abgeschlossen ist, hat sie die folgende Struktur Sie können sehen, dass das ** Migrationsverzeichnis ** und die ** alembic.ini-Datei ** erstellt wurden

tree


.
├── README.md
├── docker-compose.yml
└── src
    ├── alembic.ini
    ├── migration
    │   ├── README
    │   ├── env.py
    │   ├── script.py.mako
    │   └── versions
    └── model.py

Informationen zu den von alembic init generierten Dateien

Führen Sie die Migration aus

Alembic.ini bearbeiten

Bearbeiten Sie die Datei alembic.ini, um eine Verbindung zur Datenbank herzustellen Schreiben Sie den folgenden Teil der INI-Datei mit DB-Verbindungsinformationen neu

alembic.ini (vor dem Bearbeiten)


sqlalchemy.url = driver://user:pass@localhost/dbname

alembic.ini (nach der Bearbeitung)


sqlalchemy.url = postgresql://postgres:postgres@alembic-db:5432/almebic

Verwenden Sie die in ** docker-compose.yml ** beschriebenen Verbindungsinformationen

Erstellen einer Migrationsdatei

Erstellen Sie eine Migrationsdatei mit dem Befehl ** revision **

alembic revision -m {Dateiname}

Erstellen einer Migrationsdatei


root@ecce2b20848e:/usr/src# alembic revision -m "create account table"
  Generating /usr/src/migration/versions/b5f586d58141_create_account_table.py ...  done

Nach der Ausführung wird eine Migrationsdatei im Versionsverzeichnis erstellt.

b5f586d58141_create_account_table.py


"""create account table

Revision ID: b5f586d58141
Revises:
Create Date: 2020-05-02 17:49:20.493493

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'b5f586d58141'
down_revision = None
branch_labels = None
depends_on = None


def upgrade():
    pass


def downgrade():
    pass

Migrationsdatei bearbeiten

Bearbeiten Sie die generierte Migrationsdatei Hier kopieren wir den Beamten und erstellen eine Kontotabelle

b5f586d58141_create_account_table.py


"""create account table

Revision ID: b5f586d58141
Revises:
Create Date: 2020-05-02 17:49:20.493493

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'b5f586d58141'
down_revision = None
branch_labels = None
depends_on = None


def upgrade():
    op.create_table(
        'account',
        sa.Column('id', sa.Integer, primary_key=True),
        sa.Column('name', sa.String(50), nullable=False),
        sa.Column('description', sa.Unicode(200)),
    )

def downgrade():
    op.drop_table('account')

Führen Sie die Migration aus

Führen Sie die Migration mit dem Befehl ** upgrade ** aus

alembic upgrade head

** head ** führt die Migration auf die neueste Version durch Wenn Sie nur eine Version erhöhen möchten, verwenden Sie ** + 1 ** anstelle von head Wenn Sie die Version verringern möchten, verwenden Sie den Befehl ** downgrade ** Wenn Sie zum Ausgangszustand zurückkehren möchten

alembic downgrade base

Laufen Verwenden Sie ** -1 ** anstelle von base, um zur vorherigen Version zurückzukehren

Führen Sie die Migration aus


root@ecce2b20848e:/usr/src# alembic upgrade head
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> b5f586d58141, create account table

Generieren Sie automatisch eine Migrationsdatei

Durch Bearbeiten von env.py wie in Dokumentation zur automatischen Generierung von Migrationen - Alembic 1.4.2 beschrieben. Aus den Informationen des in Python definierten ** SQLAlchemy ** -Modells kann automatisch eine Migrationsdatei erstellt werden. Definieren Sie zunächst das Modell mit SQLAlchemy

SQLAlchemy-Modelldefinition

Definieren Sie in der Modelldefinition die Kontotabelle, die zuvor im SQLAlchemy-Modell hinzugefügt wurde. Fügen Sie Spalten für ** created_at ** und ** updated_at ** hinzu Ich möchte die SQLAlchemy Engine an env.py übergeben, also definieren Sie sie

model.py


from datetime import datetime

from sqlalchemy import create_engine, Column, String, Integer, Unicode, DateTime
from sqlalchemy.ext.declarative import declarative_base

#Erstellen einer Engine
Engine = create_engine(
    "postgresql://postgres:postgres@alembic-db:5432/almebic",
    encoding="utf-8",
    echo=False
)

'''
Erstellen Sie eine Modellbasis
Wenn Sie ein Modell basierend auf dieser Basis definieren, werden Modellinformationen in Metadaten gespeichert.
'''
ModelBase = declarative_base()


class AcountModel(ModelBase):
    """
    AcountModel
    """
    __tablename__ = 'account'

    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    description = Column(Unicode(200))
    created_at = Column(DateTime, default=datetime.now, nullable=False)
    updated_at = Column(DateTime, default=datetime.now, nullable=False)

Env.py bearbeiten

Bearbeiten Sie env.py, damit Sie Informationen zu dem in model.py definierten Modell erhalten Importieren Sie die zuvor definierten ** ModelBase ** und ** Engine ** Ersetzen Sie ** ModelBase.metadata ** durch ** target_metadata ** Bearbeiten Sie außerdem ** run_migrations_online () **, wenn Sie eine Migration durchführen, damit die Migration durchgeführt wird.

env.py


from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool

from alembic import context
from model import ModelBase, Engine

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = ModelBase.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.

    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(
        url=url,
        target_metadata=target_metadata,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
    )

    with context.begin_transaction():
        context.run_migrations()


def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    url = config.get_main_option("sqlalchemy.url")
    connectable = Engine

    with connectable.connect() as connection:
        context.configure(
            url=url,
            connection=connection,
            target_metadata=target_metadata
        )

        with context.begin_transaction():
            context.run_migrations()


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()

Durchführen der Migration mit Autogenerate

Der Revisionsbefehl mit der Option ** --autogenerate ** erstellt eine Migrationsdatei aus den in SQLAlchemy definierten Modellinformationen.

Revisionsbefehl (--Mit autogenerate)


root@9a7582105665:/usr/src# alembic revision --autogenerate -m "Added columns."
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.ddl.postgresql] Detected sequence named 'account_id_seq' as owned by integer column 'account(id)', assuming SERIAL and omitting
INFO  [alembic.autogenerate.compare] Detected added column 'account.created_at'
INFO  [alembic.autogenerate.compare] Detected added column 'account.updated_at'
  Generating /usr/src/migration/versions/dcd0d354f648_added_columns.py ...  done

Die folgenden Dateien werden nach der Ausführung erstellt

dcd0d354f648_added_columns.py


"""Added columns.

Revision ID: dcd0d354f648
Revises: b5f586d58141
Create Date: 2020-05-02 18:58:03.864154

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'dcd0d354f648'
down_revision = 'b5f586d58141'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('account', sa.Column('created_at', sa.DateTime(), nullable=False))
    op.add_column('account', sa.Column('updated_at', sa.DateTime(), nullable=False))
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('account', 'updated_at')
    op.drop_column('account', 'created_at')
    # ### end Alembic commands ###

Danach wird die Migration mit dem Upgrade-Befehl abgeschlossen

Bonus

Was ist, wenn ich die durch die Migration generierte Datei umbenennen möchte?

Bearbeiten Sie alembic.ini, wenn Sie die Namenskonvention anstelle von "dcd0d354f648_added_columns.py" ändern möchten (z. B. um Datumsinformationen einzuschließen). Bearbeiten Sie ** file_template ** in alembic.ini

Beispiel


file_template = %%(year)d%%(month).2d%%(day).2d-%%(hour).2d%%(minute).2d_%%(slug)s

Wird die automatische Generierung Änderungen erkennen?

Bitte beachten Sie, dass einige Änderungen möglicherweise nicht erkannt werden. Siehe unten für Details Auto Generating Migrations — Alembic 1.4.2 documentation

Recommended Posts

Ich habe versucht, alembic auszuführen, ein Migrationstool für Python
Ich habe versucht, Python aus einer Bat-Datei auszuführen
[Python] Ich habe versucht, einen lokalen Server mit flask auszuführen
Ich habe es mit Grumpy versucht (Python ausführen).
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe eine funktionale Sprache mit Python ausprobiert
Ich habe ein Passwort-Tool in Python erstellt.
[5.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[2nd] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[3.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[4.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[1.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe versucht, Pymc auszuführen
Ich habe versucht, mit Python ein Tippspiel zu spielen
Ich habe Python> autopep8 ausprobiert
Ich habe versucht, eine CSV-Datei mit Python zu lesen
Ich habe versucht, mit Python Faiss zu laufen, Go, Rust
Ich habe versucht, Python -m summpy.server -h 127.0.0.1 -p 8080 auszuführen
Ich habe versucht, ein Python 3-Modul in C hinzuzufügen
Ich habe versucht, Deep Floor Plan mit Python 3.6.10 auszuführen.
Ich habe Python> Decorator ausprobiert
Ich habe versucht, TensorFlow auszuführen
Ich habe versucht, ein scheinbar Windows-Snipper-Tool mit Python zu implementieren
Ich habe versucht, einen Pseudo-Pachislot in Python zu implementieren
Ich habe versucht, mit Python eine Pseudofraktalfigur zu zeichnen
Ich habe versucht, Python (3) anstelle eines Funktionsrechners zu verwenden
Python: Ich habe es mit Lügner und Ehrlichkeit versucht
Ich habe fp-Wachstum mit Python versucht
Ich habe versucht, mit Python zu kratzen
Ich habe die C-Erweiterung von Python ausprobiert
Ich habe einen Python-Text gemacht
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, einen eindimensionalen Zellautomaten in Python zu implementieren
[Markov-Kette] Ich habe versucht, die Zitate in Python einzulesen.
Ich habe versucht, "ein Programm, das doppelte Anweisungen in Python entfernt"
Ich habe versucht, Tensorboard zu verwenden, ein Visualisierungstool für maschinelles Lernen
Ich habe versucht "Wie man eine Methode in Python dekoriert"
Ich habe eine Klasse in Python erstellt und versucht, Enten zu tippen
Ich habe eine Stoppuhr mit tkinter mit Python gemacht
Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren
Ich habe versucht, Python zu berühren (Installation)
Ich habe versucht, WebScraping mit Python.
Ich habe mit Python eine Lotterie gemacht.
Ich habe versucht, GAN in Colaboratory auszuführen
Ich habe versucht, Thonny (Python / IDE) zu verwenden.
[Python] Memo zum Erstellen von Scraping-Tools
Ich habe mit Python einen Daemon erstellt
Ich habe Line Benachrichtigung in Python versucht
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, eine Python-Datei in eine EXE-Datei zu verwandeln (Rekursionsfehler unterstützt)
Ich habe versucht, das Python Package Repository (Warehouse) auszuführen, das PyPI unterstützt
Ich habe versucht, mit Python einen regulären Ausdruck für "Betrag" zu erstellen
Ich habe versucht, mit Python einen regulären Ausdruck von "Zeit" zu erstellen
[Python] Ein Memo, das ich versucht habe, mit Asyncio zu beginnen
Ich habe versucht, Platypus auszuführen, um ein kleines Optimierungsproblem zu lösen - Teil 2
Ich habe versucht, mit Python eine Liste von Primzahlen zu erstellen
Ich habe versucht, mit Python einen regulären Ausdruck von "Datum" zu erstellen
Ich habe versucht, ein missverstandenes Gefangenendilemma in Python zu implementieren