Alembic — начальная миграция sqlalchemy

У меня возникла проблема с созданием начальной миграции, в которой автоматически будут таблицы, которые я определил в своих моделях.py, используя общую базу (declarative_base).

Когда я ввожу команду:

alembic revision --autogenerate

alembic создает пустой файл.

Что не так в моих конфигах или моем подходе?

проект.base.py:

from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()

env.py:

import sys
import os

sys.path.append(os.path.abspath(os.getcwd()))
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig

from project.base import Base
target_metadata = Base.metadata
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.

    """
    engine = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix='sqlalchemy.',
        poolclass=pool.NullPool)

    connection = engine.connect()
    context.configure(
        connection=connection,
        target_metadata=target_metadata
    )

    # target_metadata.reflect(engine, only=[
    #     "django_migrations",
    #     "auth_group_permissions",
    #     "django_session",
    #     "auth_user_user_permissions",
    #     "auth_user_groups",
    #     "django_admin_log",
    #     "auth_permission",
    #     "auth_user",
    #     "sysdiagrams",
    #     "django_content_type",
    #     "auth_group",
    #     "sysdiagrams",
    # ])

    try:
        with context.begin_transaction():
            context.run_migrations()
    finally:
        connection.close()


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

Образец модели:

# -*- coding: utf-8 -*-

from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, SmallInteger
from sqlalchemy.orm import relationship, backref
from project.base import Base


__schema__ = "Users"


class User(Base):
    __tablename__ = "User"
    __table_args__ = {'schema': __schema__}

    USER_CUSTOMER = 0
    USER_EMPLOYEE = 5
    USER_ADMIN = 10

    USER_TYPES = (
        (USER_CUSTOMER, u'Klient'),
        (USER_EMPLOYEE, u'Obsługa sklepu'),
        (USER_ADMIN, u'Administrator')
    )

    id = Column(Integer, primary_key=True)
    name = Column(String(255))
    email = Column(String(255))
    password = Column(String)
    date_created = Column(DateTime)
    date_updated = Column(DateTime)
    user_type = Column(SmallInteger)

    is_active = Column(Boolean)

    def __repr__(self):
        return u"<User: ({} {})>".format(self.id, self.name)

    def is_management(self):
        return self.user_type in [self.USER_EMPLOYEE, self.USER_ADMIN]

    def is_admin(self):
        return self.user_type == self.USER_ADMIN

Редактировать:

Я обнаружил, что Base.metadata.sorted_tables пусто.


person Efrin    schedule 08.10.2014    source источник


Ответы (1)


В дополнение к импорту вашего декларативного класса Base вам также необходимо импортировать все ваши модели. Что-то вроде import project.models или любых других модулей, которые вы должны включить, чтобы все классы вашей модели были импортированы. В противном случае ваш Base.metadata не будет заполнен определениями вашей модели, поскольку env.py никогда их не включает.

person dgilland    schedule 09.10.2014
comment
Если вы похожи на меня и уже определили таблицу, обязательно переименуйте существующие таблицы, например. с суффиксом _old выполните генерацию перегонного куба, удалите лишние операторы удаления в сценарии автогенерации (он найдет ваши переименованные таблицы и создаст операторы удаления/создания) и, наконец, переименуйте таблицы обратно. Вероятно, должна быть опция --init, которую вы можете передать для автоматической генерации, чтобы это не было круговым движением... - person smaudet; 10.10.2019