Как разделить models.py на разные файлы для разных моделей в Pyramid?

Я новичок в пирамиде и изо всех сил пытался внести некоторые изменения в свой проект. Я пытаюсь разделить свои модели/классы на отдельные файлы вместо одного файла models.py. Для этого я удалил старый файл models.py и создал папку моделей с файлом __init__.py вместе с одним файлом для каждого класса. В __init__.py я импортировал класс, используя from .Foo import Foo.

Это заставляет представления работать правильно, и они могут инициализировать объект.

Но запуск сценария initializedb не создает новые таблицы, как это было, когда у меня были все модели в одном файле models.py. Он не создает соответствующие таблицы, а напрямую пытается вставить в них.

Может ли кто-нибудь привести мне пример структуры проекта пирамиды, в которой есть модели в разных файлах?


person Karan    schedule 27.04.2012    source источник


Ответы (2)


myapp
    __init__.py
    scripts
        __init__.py
        initialize_db.py
    models
        __init__.py
        meta.py
        foo.py
        moo.py

теперь meta.py может содержать общий Base, а также DBSession:

Base = declarative_base()
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension))

Каждый foo.py и moo.py могут импортировать свою общую базу из meta.py.

from .meta import Base

class Foo(Base):
    pass

Чтобы убедиться, что все ваши таблицы подобраны, из подпакета models и для удобства вы можете импортировать их в models/__init__.py:

from .meta import DBSession
from .foo import Foo
from .moo import Moo

Без выполнения чего-то подобного различные таблицы не будут присоединены к Base и, следовательно, не будут созданы при вызове create_all.

Затем ваш скрипт initialize_db может создать все таблицы через

from myapp.models.meta import Base
Base.metadata.create_all(bind=engine)

Ваши представления могут импортировать модели для получения прибыли:

from myapp.models import DBSession
from myapp.models import Foo
person Michael Merickel    schedule 27.04.2012
comment
Спасибо за ответ! Мне любопытно узнать, зачем нам нужен один и тот же объект Base во всех моделях. Я думал, что Base будет неким статическим/общим объектом, который будет собирать все метаданные независимо от того, откуда он вызывается. - person Karan; 27.04.2012
comment
Вам не нужна одна и та же база или метаданные, но это, безусловно, помогает сохранять ясность. Каждое ядро ​​базы данных должно иметь один объект метаданных, описывающий схему для этого ядра. В python модули выполняются только тогда, когда вы их импортируете, поэтому, когда вы разбиваете файл models.py на несколько отдельных модулей, они не будут выбраны, пока каждый из них не будет импортирован. - person Michael Merickel; 28.04.2012

У меня была такая же проблема однажды.

Решение для разделенных файлов модели: вы должны инициализировать все базовые (родительские) классы из ваших файлов отдельно:

#initializedb.py
...
from project.models.Foo import Base as FooBase
from project.models.Moo import Base as MooBase
...

def main(argv=sys.argv):
    ...
    FooBase.metadata.create_all(engine)
    MooBase.metadata.create_all(engine)
person Vitalii Ponomar    schedule 27.04.2012
comment
Не уверен, что это лучший путь. Я бы предпочел попытаться импортировать Base в каждый файл модели. - person Antoine Leclair; 27.04.2012
comment
@Antoine: я думаю, что from project.models.Foo import Base as FooBase означает, что в каждом файле модели есть база. И я уже делаю это, но это не работает. @Vitali: Вы знаете, почему мы должны делать это окольными путями, чтобы создавать отдельные базы для каждой модели? - person Karan; 27.04.2012
comment
@KaranK: Мое предложение состояло в том, чтобы иметь один Base в одном файле и импортировать этот Base в каждый файл модели. Я не уверен, что отношения будут работать, если вы используете разные базы. - person Antoine Leclair; 27.04.2012
comment
@Antoine: ответ Майкла похож на то, что вы сказали. Большое спасибо! - person Karan; 27.04.2012