【问题标题】:How do I split models.py into different files for different models in Pyramid?如何将 models.py 拆分为 Pyramid 中不同模型的不同文件?
【发布时间】:2012-04-28 01:22:47
【问题描述】:

我是金字塔新手,一直在努力对我的项目进行一些更改。我正在尝试将我的模型/类拆分为单个文件,而不是单个 models.py 文件。为此,我删除了旧的 models.py 并创建了一个带有 __init__.py 文件的模型文件夹以及每个类的一个文件。在__init__.py 中,我使用from .Foo import Foo 导入了该类。

这使得视图可以正常工作并且它们可以初始化一个对象。

但是运行 initializedb 脚本并不会像我在单个 models.py 中拥有所有模型时那样创建新表。它不会创建相关表,而是直接尝试插入其中。

谁能给我一个金字塔项目结构的例子,它在不同的文件中有模型?

【问题讨论】:

    标签: python model-view-controller pyramid


    【解决方案1】:
    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.pymoo.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
    

    【讨论】:

    • 感谢您的回答!我很想知道为什么我们在所有模型中都需要相同的 Base 对象。我认为 Base 将是一些静态/共享对象,它会拾取所有元数据,无论从何处调用它。
    • 您不需要相同的基础或元数据,但它确实有助于保持清晰。每个数据库引擎都应该有一个描述该引擎架构的元数据对象。在 python 中,模块只有在你导入它们时才会执行,所以当你将 models.py 分解成多个单独的模块时,它们将不会被拾取,直到它们都被导入。
    【解决方案2】:

    我曾经遇到过同样的问题。

    拆分模型文件的解决方案:您必须分别从文件中初始化所有 Base(父)类:

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

    【讨论】:

    • 不确定这是最好的方法。我宁愿尝试在每个模型文件中导入 Base。
    • @Antoine:我认为from project.models.Foo import Base as FooBase 表示每个模型文件中都有一个Base。我已经在这样做了,但它不起作用。 @Vitali:你知道为什么我们必须以迂回的方式来为每个模型创建单独的基础吗?
    • @KaranK:我的建议是在一个文件中包含一个 Base,然后在每个模型文件中导入该 Base。如果您使用不同的 Base,我不确定这些关系是否有效。
    • @Antoine:迈克尔的回答和你说的差不多。非常感谢!
    猜你喜欢
    • 2021-07-09
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多