Как разделить декларативную модель SQLAlchemy на модули? - PullRequest
0 голосов
/ 29 июня 2018

Мне нужно определить несколько модулей, которые содержат декларативные классы SQLAlchemy. Я написал функцию в каждом модуле с именем subclass_base(), в которую экземпляр Base * из 1002 * передается после создания экземпляра. subclass_base() первого модуля правильно вызывает подклассы базового экземпляра, и подклассы видны снаружи функции. Вызов второго модуля завершается без ошибок, но как внутри функции, так и вне ее все подклассы отражаются в Base.__subclasses__ только в некоторых случаях. Вот минимальный рабочий пример только с одним определением класса в каждом модуле:

modela.py

from sqlalchemy import Column, Integer, String
def subclass_base(Base):
    class Roles(Base):
        __tablename__ = 'roles'

        id = Column(Integer, primary_key=True)
        name = Column(String(32))

modelb.py

from sqlalchemy import Column, Integer, String
def subclass_base(Base):
    class Locations(Base):
         __tablename__ = 'locations'

        id = Column(Integer, primary_key=True)
        name = Column(String(64))

test.py

from sqlalchemy.ext.declarative import declarative_base
from modela import subclass_base as amod
from modelb import subclass_base as bmod

def test():
    count = 0
    while True:
        try:
            Base = declarative_base()

            amod(Base)

            bmod(Base)
            sc = [subclass.__name__ for subclass in Base.__subclasses__()]
            assert(len(sc) == 2)

            print('.', end='')
            count += 1
        except AssertionError:
            print("Failed after {} successful pass(es)".format(count))
            count = 0

Я подозреваю, что из-за этой проблемы я упускаю из виду конкретную проблему работы с метаклассом, которая продолжается с методом Declarative_base (), но я не могу понять, что происходит. Мне также интересно, если это проблема наследования. Есть ли другой архитектурный подход, который я должен использовать вместо использования функции для создания подкласса одного базового класса?

1 Ответ

0 голосов
/ 29 июня 2018

Не определяйте класс внутри функции. Просто определите Base в одном модуле определения, затем импортируйте этот модуль из других модулей:

db.py

from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
Session = sessionmaker()

def bind_engine(engine):
    Base.metadata.bind = engine
    Session.configure(bind=engine)

modela.py

from sqlalchemy import Column, Integer, String
from db import Base

class Roles(Base):
    __tablename__ = 'roles'

    id = Column(Integer, primary_key=True)
    name = Column(String(32))

modelb.py

from sqlalchemy import Column, Integer, String
from db import Base

class Locations(Base):
    __tablename__ = 'locations'

    id = Column(Integer, primary_key=True)
    name = Column(String(64))

user_script.py

 from sqlalchemy import create_engine
 engine = create_engine('postgresql://user:pwd@server/database')
 from yourproject.db import bind_engine
 bind_engine(engine)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...