Python 导入依赖
Python Import Dependency
我知道这个问题已经被问过很多次了,但即使我尝试了很多 SO 的建议,我仍然无法正确回答。所以,在这里发帖寻求帮助。
我正在使用 Flask-Restful 和 Flask-SqlAlchemy 构建一个简单的 Web 服务器。基本上,我认为由于循环导入而出现错误。我的 Widget class 依赖于 Visualization class,反之亦然...
错误信息:
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
app/models/__init__.py:
from visualization import Visualization as VisualizationModel
from widget import Widget as WidgetModel
from dashboard import Dashboard as DashboardModel
app/models/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")
app/models/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 很陌生。如果你能帮助我,我将不胜感激。提前感谢您的帮助!
更新
定义双向关系的目的是我想在Widget对象的字段中附加Visualization对象return 对小部件记录的 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
功能,因为如果 小部件 没有 可视化 就无法存在。
将您的导入更改为如下所示:
from app import models
然后改用models.WidgetModel
/ models.VisualizationModel
。
问题是您正在创建一个循环导入依赖关系,其中两个文件都需要另一个文件已经处理过才能被处理。通过转为导入整个 models
命名空间而不是在导入时尝试导入特定模型名称,您可以避免使导入依赖于完全处理的文件。这样,两个文件都可以在尝试调用另一个文件创建的对象之前得到完全处理。
在这种情况下它可能仍然不起作用,但是因为您试图立即在 class 定义的一部分中使用导入,该定义在处理时进行评估。
您似乎在尝试定义双向关系 - backref
参数旨在自动执行此操作,而无需您在两个模型上指定关系。 (backref
告诉 sqlalchemy 将什么字段添加到 other 模型以指向回 link 的原始模型)。因此,您可能不需要首先进行这两项导入。
例如,Visualization.widget
是用 backref="visualizations"
定义的,这意味着 Widget.visualizations
将 已经存在 - 你不需要显式创建它。
如果您特别需要的是 many:many 关系,那么您真正想要做的很可能是 define an association table for the many-to-many relationship。
我知道这个问题已经被问过很多次了,但即使我尝试了很多 SO 的建议,我仍然无法正确回答。所以,在这里发帖寻求帮助。
我正在使用 Flask-Restful 和 Flask-SqlAlchemy 构建一个简单的 Web 服务器。基本上,我认为由于循环导入而出现错误。我的 Widget class 依赖于 Visualization class,反之亦然...
错误信息:
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
app/models/__init__.py:
from visualization import Visualization as VisualizationModel
from widget import Widget as WidgetModel
from dashboard import Dashboard as DashboardModel
app/models/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")
app/models/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 很陌生。如果你能帮助我,我将不胜感激。提前感谢您的帮助!
更新
定义双向关系的目的是我想在Widget对象的字段中附加Visualization对象return 对小部件记录的 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
功能,因为如果 小部件 没有 可视化 就无法存在。
将您的导入更改为如下所示:
from app import models
然后改用models.WidgetModel
/ models.VisualizationModel
。
问题是您正在创建一个循环导入依赖关系,其中两个文件都需要另一个文件已经处理过才能被处理。通过转为导入整个 models
命名空间而不是在导入时尝试导入特定模型名称,您可以避免使导入依赖于完全处理的文件。这样,两个文件都可以在尝试调用另一个文件创建的对象之前得到完全处理。
在这种情况下它可能仍然不起作用,但是因为您试图立即在 class 定义的一部分中使用导入,该定义在处理时进行评估。
您似乎在尝试定义双向关系 - backref
参数旨在自动执行此操作,而无需您在两个模型上指定关系。 (backref
告诉 sqlalchemy 将什么字段添加到 other 模型以指向回 link 的原始模型)。因此,您可能不需要首先进行这两项导入。
例如,Visualization.widget
是用 backref="visualizations"
定义的,这意味着 Widget.visualizations
将 已经存在 - 你不需要显式创建它。
如果您特别需要的是 many:many 关系,那么您真正想要做的很可能是 define an association table for the many-to-many relationship。