2012-04-27 10 views
9

Jestem nowy w piramidzie i staram się wprowadzić pewne zmiany w moim projekcie. Próbuję podzielić moje modele/klasy na pojedyncze pliki zamiast pojedynczego pliku models.py. W tym celu usunąłem stary models.py i utworzyłem folder modeli z plikiem __init__.py wraz z jednym plikiem dla każdej klasy. W wersji __init__.py zaimportowałem klasę za pomocą from .Foo import Foo.Jak podzielić models.py na różne pliki dla różnych modeli w Pyramid?

Dzięki temu widoki działają poprawnie i mogą zainicjować obiekt.

Jednak uruchomienie skryptu initializedb nie tworzy nowych tabel, tak jak miało to miejsce, gdy wszystkie modele miałem w jednym modelu. Nie tworzy odpowiednich tabel, ale bezpośrednio próbuje je wstawić.

Czy ktoś może podać przykład piramidalnej struktury projektu, która ma modele w różnych plikach?

Odpowiedz

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

teraz meta.py może zawierać wspólny Base jak również DBSession:

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

Każdy foo.py i moo.py może importować ich wspólną bazę z meta.py.

from .meta import Base 

class Foo(Base): 
    pass 

Aby upewnić się, że wszystkie stoły są zabierani z wewnątrz models podpakiecie, a dla wygody, można importować je do models/__init__.py:

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

Bez robi coś tak różne tabele nie zostanie dołączony do Base i dlatego nie zostanie utworzony po wywołaniu create_all.

Twój initialize_db skrypt może następnie utworzyć wszystkie tabele poprzez

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

swoje poglądy mogą importować modele z zyskiem:

from myapp.models import DBSession 
from myapp.models import Foo 
+0

Dzięki za odpowiedź! Jestem ciekawy, dlaczego potrzebujemy tego samego obiektu Base we wszystkich modelach. Myślałem, że Base będzie jakimś statycznym/współdzielonym obiektem, który zbiera wszystkie metadane, niezależnie od tego, gdzie jest wywoływany. – KaranK

+0

Nie potrzebujesz tej samej bazy ani metadanych, ale z pewnością pomaga to w utrzymaniu porządku. Każdy aparat bazy danych powinien mieć jeden obiekt metadanych, który opisuje schemat tego silnika. W pythonie moduły są wykonywane tylko wtedy, gdy je importujesz, więc po rozbiciu modelu .ps na wiele pojedynczych modułów, nie zostaną one pobrane, dopóki nie zostaną zaimportowane. –

0

Raz miałem ten sam problem.

rozwiązywania dla splited plików modelowych: musisz zainicjować wszystkie podstawa (dominująca) zajęcia z plików oddzielnie:

#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) 
+1

Nie wiesz, że to najlepszy sposób, aby przejść. Wolałbym zaimportować Base w każdym pliku modelu. –

+0

@Antoine: Myślę, że 'from project.models.Foo import Base jako FooBase' oznacza, że ​​w każdym pliku modelu znajduje się baza. I już to robię, ale to nie działa. @Vitali: Czy wiesz, dlaczego musimy robić to w okrężny sposób, aby stworzyć oddzielne podstawy dla każdego modelu? – KaranK

+0

@KaranK: Moja sugestia polegała na tym, aby w jednym pliku mieć pojedynczą "Bazę" i zaimportować 'Bazę' w każdym pliku modelu. Nie jestem pewien, czy te związki zadziałają, jeśli użyjesz różnych Podstaw. –

Powiązane problemy