【问题标题】:How can I avoid a circular import in this case (Flask and SQLalchemy)?在这种情况下如何避免循环导入(Flask 和 SQLalchemy)?
【发布时间】:2013-07-01 11:21:07
【问题描述】:

我有一个使用 SQLalchemy 作为数据库的 FLASK 应用程序。

模型都在models.py中,我在大多数模型类的默认ORM属性和方法中添加了几个属性和方法。 例如;我的“合同”模型有一个额外的属性 contract.first_possible_termination 返回一个日期。

问题是这个属性访问了一个 utilities 模块,该模块具有计算日期范围的功能。并且该功能需要使用存储在数据库中的“配置”表中的不同配置选项。

所以实用程序模块需要再次使用 ORM 模型来访问配置表,因此我们有一个循环导入:

ImportError: cannot import name Configuration

我想知道在这里避免循环导入的标准方法是什么。我想更多的人会遇到这种情况,因为有人会在模型中添加方法和属性。

编辑,请注意:
我认为植物人的回答通常是最好的方法,因为它促进了 SoC,但在我的具体情况下,我正在使用一个遗留数据库,该数据库具有影响分布在数据库中不同表中的业务规则的值。
我添加到模型中的许多功能将以某种方式依赖于这些值/业务规则,因此如果不进行大量重构并传递大量额外的外部数据,我将无法避免在这些函数中访问数据库我的辅助函数的值。

我只能接受一个答案,但两者都是有效的,所以对两者都投赞成票,但 Blubber 的答案是我目前的个人解决方案。
感谢 Blubber 和 Plantian。

【问题讨论】:

    标签: python sqlalchemy circular-dependency


    【解决方案1】:

    您可以在函数内部而不是在模块顶部导入模块,模块只导入一次,因此这不会造成性能问题。

    您也可以尝试将配置模块导入移动到您的 util 模块的底部。

    【讨论】:

    • 嗨,Blubber,这行得通,但是将导入移动到方法内部而不是页面顶部不是 Pythonic 吗?这是 Python 循环导入的标准做法吗?
    【解决方案2】:

    另一种选择是将配置作为参数传递给实用程序函数。最好不要让您的实用程序直接依赖于模型。即。

    def get_range (start_at, strategy):
        pass
    

    策略由调用者确定(来自配置表)。也许你的 util 函数的代码 sn-p 会更容易构建。

    【讨论】:

    • 感谢 Plantian,我已经想到了这一点,但这是一个会员系统,其中许多小型辅助函数依赖于数据库中的值。例如,成员资格的开始日期可能是成员开始的日期,或者是下一个借记期的开始日期,这可以在成员资格中进行配置。数据库中存储了几十条这样的业务规则……
    猜你喜欢
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多