Saya ingin bermigrasi melalui Alembic, tetapi sesuatu tidak berfungsi. Saya tidak mengerti apa sebenarnya yang saya lakukan salah.

Alembic saya .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()

File db.py saya:

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)

Dan {models.py saya:

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)

Setelah menggunakan alembic revision -m "first", itu tidak memigrasikan model saya.

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

def upgrade():
    pass


def downgrade():
    pass

Saya sudah menulis dalam konsol alembic revision --autogenerate -m "razraz" dan itu membuat tabel basis data alembic, tetapi migrasi masih belum berfungsi.

0
Abduhamidov Jordan 3 April 2021, 16:27

1 menjawab

Jawaban Terbaik

Kesalahan ini disebabkan oleh penggunaan declarative_base() dari sqlalchemy.

Sqlalchemy terdiri dari dua bagian utama:

  • ORM - yang merupakan objek pemetaan relasional objek dengan model, hubungan, permintaan dll.
  • core - yang jauh lebih 'mentah' dan dasar dan secara umum terkait dengan penciptaan tabel dan kolom, serta generasi kueri (bergabung, di mana klausa, dll.)

Di ormar hanya yang terakhir yang digunakan dan Anda tidak dapat menerapkan konsep apa pun dari ORM bagian. Bahkan ormar adalah jenis (disederhanakan oleh async dan pydantic berbasis) setara dengan bagian ORM.

Itu berarti Anda tidak dapat mewarisi dari Base & lt; - itulah bagian ORM yang saya sebutkan.

Jadi sampel Anda harus terlihat seperti mengikuti cuplikan:

Alembic .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()

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

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

Penafian: Saya pencipta ormar - Jika Anda memiliki lebih banyak pertanyaan atau masalah dengan membuatnya berfungsi, beri tahu saya di sini. Jika itu memecahkan masalah Anda ingat untuk menandai jawaban yang diterima.

Terima kasih!

1
collerek 3 April 2021, 15:39