Python导入依赖项

时间:2016-10-16 00:45:59

标签: python flask-sqlalchemy flask-restful

我知道这个问题已被多次询问,但即使在我尝试了很多SO建议之后,我仍然无法做到正确。所以,张贴在这里寻求帮助。

我正在使用Flask-Restful和Flask-SqlAlchemy构建一个简单的Web服务器。基本上,我认为由于循环导入我收到错误。我的 Widget 类依赖于 Visualization 类,反之亦然...

错误消息:

Traceback (most recent call last):
  File "server.py", line 1, in <module>
    from app.resources.dashboard import Dashboards, Dashboard
  File "app/__init__.py", line 14, in <module>
    from models import *
  File "app/models/__init__.py", line 1, in <module>
    import visualization.Visualization as VisualizationModel
  File "app/models/visualization.py", line 3, in <module>
    from app.models import WidgetModel
ImportError: cannot import name WidgetModel

目录结构:

├── app
│   ├── app/__init__.py
│   ├── app/models
│   │   ├── app/models/__init__.py
│   │   ├── app/models/dashboard.py
│   │   ├── app/models/visualization.py
│   │   ├── app/models/widget.py
│   └── app/resources
│       ├── app/resources/__init__.py
│       ├── app/resources/dashboard.py
│       ├── app/resources/visualization.py
│       ├── app/resources/widget.py
├── server.py

应用程序/模型/ __ INIT __ PY:

from visualization import Visualization as VisualizationModel
from widget import Widget as WidgetModel
from dashboard import Dashboard as DashboardModel

应用程序/模型/ visualization.py

from sqlalchemy import types
from app import db
from app.models import WidgetModel


class Visualization(db.Model):
    __tablename__ = 'visualizations'
    ...
    widget = db.relationship(WidgetModel, cascade="all, delete-orphan", backref="visualizations")

应用程序/模型/ widget.py

from app import db
from app.models import VisualizationModel


class Widget(db.Model):
    __tablename__ = 'widgets'
    ...
    visualization = db.relationship(VisualizationModel, backref="widgets")

我尝试将导入更改为from app import models,然后使用models.WidgetModel / models.VisualizationModel。但是,仍然会遇到ImportError。

错误讯息:

Traceback (most recent call last):
  File "server.py", line 1, in <module>
    from app.resources.dashboard import Dashboards, Dashboard
  File "app/__init__.py", line 14, in <module>
    from models import *
  File "app/models/__init__.py", line 1, in <module>
    from visualization import Visualization as VisualizationModel
  File "app/models/visualization.py", line 3, in <module>
    from app import models
ImportError: cannot import name models

我是Python的新手。如果你能帮助我,我将不胜感激。谢谢你提前帮忙!

更新

定义双向关系的意图是我想在窗口小部件记录上返回GET请求时在窗口小部件对象的字段中附加可视化对象

在app / resources / widget.py中我有:

...
from flask_restful import fields, Resource, marshal_with, abort
from app.models import WidgetModel
import visualization as visualizationResource


widget_fields = {
    'id': fields.String,
    ...
    'dashboard_id': fields.String,
    'visualization_id': fields.String,
    'visualization': fields.Nested(visualizationResource.visualization_fields)
}

class Widgets(Resource):

    @marshal_with(widget_fields)
    def get(self):
        return WidgetModel.query.all()

我还希望拥有cascade delete功能,因为如果没有可视化小部件就不能存在。

1 个答案:

答案 0 :(得分:1)

将导入更改为如下所示:

from app import models

然后使用models.WidgetModel / models.VisualizationModel代替。

问题是您正在创建一个循环导入依赖项,其中两个文件都要求在处理之前已经处理了另一个文件。通过转移导入整个models命名空间而不是在导入时尝试导入特定的模型名称,可以避免导入依赖于完全处理的文件。这样,在尝试调用另一个创建的对象之前,可以完全处理这两个文件。

在这种情况下,它可能仍然不起作用,因为您试图立即在类定义的一部分中使用导入,该定义在处理时进行评估。

看起来您正在尝试定义双向关系 - backref参数旨在自动执行此操作,而无需在两个模型上指定关系。 (backref告诉sqlalchemy要添加到其他模型的哪个字段指向链接到它的原始模型。因此,您可能不需要首先执行这两种导入。

例如,Visualization.widget定义为backref="visualizations"这一事实意味着Widget.visualizations已经存在 - 您无需明确创建它。

如果您特别需要的是很多:很多关系,那么您实际想做的事情就是define an association table for the many-to-many relationship