Jag går en kurs i Python, programmeringsspråket. En av de sista uppgifterna är att skapa en hemsida, egentligen en portfolio med program jag skapat och länkar till Github med flera ställen där jag har något jag vill visa upp. I kursen använde vi SQLite som databas men eftersom jag använd MySql mycket i mina andra projekt så ville jag göra det här med. Plus att det blev en liten utmaning att göra om databaskopplingar.
För att på ett enkelt sätt kunna göra databasmigreringar när jag uppgraderar mitt program hittade jag Alembic som fungerar bra för det. Sökvägarna behöver rättas utifrån varje projekt, förstås men gången är denna:
1. Installera Alembic
Om du inte redan har det:
pip install alembic
2. Initiera Alembic
I roten av ditt projekt (där din app/-mapp och run.py eller liknande ligger):
alembic init migrations
Det skapar en migrations/-mapp och en alembic.ini-fil.
3. Konfigurera alembic.ini
Öppna alembic.ini och ändra denna rad:
sqlalchemy.url = driver://user:pass@localhost/dbname
Byt ut den mot din databas-url, t.ex.:
sqlalchemy.url = mysql+pymysql://root:password@localhost/portfolio-db
Eller om du använder en .env-fil – då ändrar vi detta i steg 5 istället via Python.
4. Peka Alembic till din SQLAlchemy-modell
Öppna migrations/env.py och leta upp detta block:
from logging.config import fileConfig
from sqlalchemy import engine_from_config, pool
from alembic import context
Lägg till din models.py-import (efter importerna ovan):
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from app.models import db # Lägg till detta
Byt ut denna rad:
target_metadata = None
mot:
target_metadata = db.metadata
5. (Valfritt) Använd din DATABASE_URL från .env
Om du vill använda os.getenv("DATABASE_URL"):
Byt ut i migrations/env.py (under config = context.config):
from dotenv import load_dotenv
load_dotenv()
from sqlalchemy.engine.url import URL
config.set_main_option("sqlalchemy.url", os.getenv("DATABASE_URL"))
6. Skapa en migrering
När du ändrar en modell (t.ex. la till description i PortfolioItem), kör:
alembic revision --autogenerate -m "Add description to portfolio item"
Det skapar en versionsfil i migrations/versions/.
7. Kör migreringen
alembic upgrade head
Nu har kolumnen description skapats i databasen utan att radera något!
alembic.ini
Byt ut din befintliga alembic.ini med denna:
[alembic]
script_location = migrations
sqlalchemy.url = mysql+pymysql://root:password@localhost/portfolio-db
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stdout,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
Byt root:password om du har en annan användare eller databas.
migrations/env.py
Byt ut hela innehållet i migrations/env.py med detta:
from __future__ import with_statement
import sys
import os
from logging.config import fileConfig
from sqlalchemy import engine_from_config, pool
from alembic import context
# Lägg till appens rot till sys.path
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
# Importera extensions och modeller
from app.extensions import db
from app.models import *
# Load environment variables
from dotenv import load_dotenv
load_dotenv()
# Alembic Config
config = context.config
# Sätt databas-URL från .env
config.set_main_option('sqlalchemy.url', os.getenv("DATABASE_URL"))
# Loggkonfiguration
fileConfig(config.config_file_name)
# Metadata från modellerna
target_metadata = db.metadata
def run_migrations_offline():
"""Kör migreringar utan en DB-anslutning."""
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():
"""Kör migreringar med en DB-anslutning."""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
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()
Klar att köra:
Nu kan du köra:
alembic revision --autogenerate -m "Add description field"
alembic upgrade head


Lämna ett svar