ormar 中的 Alembic 迁移不起作用(FastAPI)

Abd*_*dan 3 postgresql database-migration fastapi python-3.9 ormar

我想通过 Alembic 进行迁移,但有些东西不起作用。我不明白我到底做错了什么。

我的蒸馏器 .env

from logging.config import fileConfig

from sqlalchemy import create_engine
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from db import ORMAR_DATABASE_URL
from alembic import context
import sys, os

sys.path.append(os.getcwd())
config = context.config

fileConfig(config.config_file_name)

from db import Base
target_metadata = Base.metadata
URL = "postgresql://admin:admin@localhost/fa_naesmi"



def run_migrations_offline():


context.configure(
    url=URL,
    target_metadata=target_metadata,
    literal_binds=True,
    dialect_opts={"paramstyle": "named"},
    user_module_prefix='sa.'
)

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


def run_migrations_online():
connectable = create_engine(URL)

with connectable.connect() as connection:
    context.configure(
        connection=connection,
        target_metadata=target_metadata,
        user_module_prefix='sa.'
    )

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


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()
Run Code Online (Sandbox Code Playgroud)

我的 db.py 文件:

import sqlalchemy
import databases
from sqlalchemy.ext.declarative import declarative_base
ORMAR_DATABASE_URL = "postgresql://admin:admin@localhost/fa_naesmi"

Base = declarative_base()
metadata = sqlalchemy.MetaData()
database = databases.Database(ORMAR_DATABASE_URL)
engine = sqlalchemy.create_engine(ORMAR_DATABASE_URL)
Run Code Online (Sandbox Code Playgroud)

和我的models.py

import datetime
import ormar
from typing import Optional
from db import database, metadata, Base


class MainMeta(Base, ormar.ModelMeta):
    metadata = metadata
    database = database


class Category(Base, ormar.Model):
    class Meta(MainMeta):
        pass

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
Run Code Online (Sandbox Code Playgroud)

使用后alembic revision -m "first",它不会迁移我的模型。

revision = '9176fb20d67a'
down_revision = '9159cff21eb5'
branch_labels = None
depends_on = None

def upgrade():
    pass


def downgrade():
    pass
Run Code Online (Sandbox Code Playgroud)

我已经在控制台中编写alembic revision --autogenerate -m "razraz"并创建了 alembic 数据库表,但迁移仍然无法正常工作。

小智 7

该错误是由使用declarative_base()from引起的sqlalchemy引起的。

Sqlalchemy由两个主要部分组成:

  • ORM- 这是一个具有模型、关系、查询等的对象关系映射部分。
  • core- 这是更加“原始”和基本的,一般来说它与表和列的创建以及查询生成(连接、where 子句等)有关

ormar使用后者,您不能应用该ORM部分中的任何概念。事实上ormar是(简化并async基于pydantic)等价于ORM

这意味着你不能继承Base<- 这是我提到的 orm 部分。

因此,您的示例应类似于以下片段:

蒸馏器.env

from logging.config import fileConfig
from sqlalchemy import create_engine

from db import ORMAR_DATABASE_URL
from models import metadata # adjust path if needed
from alembic import context
import sys, os

sys.path.append(os.getcwd())
config = context.config

fileConfig(config.config_file_name)

# note how it's 'raw' metadata not the one attached to Base as there is no Base
target_metadata = metadata
URL = ORMAR_DATABASE_URL


def run_migrations_offline():


context.configure(
    url=URL,
    target_metadata=target_metadata,
    literal_binds=True,
    dialect_opts={"paramstyle": "named"},
    user_module_prefix='sa.'
)

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


def run_migrations_online():
connectable = create_engine(URL)

with connectable.connect() as connection:
    context.configure(
        connection=connection,
        target_metadata=target_metadata,
        user_module_prefix='sa.'
    )

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


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()
Run Code Online (Sandbox Code Playgroud)

db.py 文件:

import sqlalchemy
import databases
ORMAR_DATABASE_URL = "postgresql://admin:admin@localhost/fa_naesmi"

# note lack of declarative_base
metadata = sqlalchemy.MetaData()
database = databases.Database(ORMAR_DATABASE_URL)
engine = sqlalchemy.create_engine(ORMAR_DATABASE_URL)
Run Code Online (Sandbox Code Playgroud)

模型.py:

import datetime
import ormar
from typing import Optional
from db import database, metadata


# you cannot subclass Base class thats ORM part
class MainMeta(ormar.ModelMeta):
    metadata = metadata
    database = database


class Category(ormar.Model):
    class Meta(MainMeta):
        pass

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
Run Code Online (Sandbox Code Playgroud)

免责声明:我是ormar- 如果您有更多问题或无法使其正常工作,请在这里告诉我。如果这解决了您的问题,请记住将答案标记为已接受。

谢谢!