2016-10-16 6 views
0

이 질문은 여러 번 묻습니다.하지만 많은 제안을 시도한 후에도 여전히 올바르게 이해할 수 없습니다. 그래서, 당신의 도움을 위해 여기에 게시.Python 가져 오기 종속성

저는 Flask-Restful 및 Flask-SqlAlchemy를 사용하여 간단한 웹 서버를 구축하고 있습니다. 기본적으로 순환 가져 오기 때문에 오류가 발생한다고 생각합니다. 내 위젯 클래스는 ... 시각화 클래스와 그 반대에 의존

오류 메시지 :

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 

파이썬에 아주 새로운 해요. 네가 나를 도울 수 있다면 나는 감사 할 것이다. 사전에 도와 줘서 고마워!


업데이트

양방향 관계를 정의의 목적은 내가 위젯에 GET 요청의 반환에 위젯 객체의 필드에 시각화 객체를 첨부 할 것입니다

기록. 내가 가진 widget.py 응용 프로그램/자원 /에서

:

나는 또한 위젯시각화 없이는 존재할 수없는 경우 때문에 cascade delete 기능을 갖고 싶어
... 
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() 

.

from app import models 

을 그리고 대신 models.WidgetModel/models.VisualizationModel를 사용

답변

1
는 다음과 같이 귀하의 수입을 변경

.

문제는 두 파일 모두 다른 파일을 처리하기 전에 이미 처리해야하는 순환 가져 오기 종속성을 만드는 것입니다. 가져 오기시 특정 모델 이름을 가져 오는 대신 전체 models 네임 스페이스를 가져 오는 것으로 이동하면 완전히 처리 된 파일에 가져 오기가 종속되는 것을 방지 할 수 있습니다.이렇게하면 두 파일 모두 다른 파일에서 만든 객체를 호출하기 전에 완전히 처리 할 수 ​​있습니다.

그러나 처리 중에 계산되는 클래스 정의의 일부에서 가져 오기를 즉시 사용하려고하기 때문에이 경우에는 여전히 작동하지 않을 수 있습니다. 당신이 양방향 관계를 정의하려는처럼


은 같습니다 - backref 매개 변수는 두 모델에 관계를 지정할 필요없이 자동으로 수행하기위한 것입니다. backref 모델에 추가 할 필드를 sqlalchemy에 알려줌으로써 해당 모델에 링크 된 원래 모델을 가리 킵니다. 따라서 처음부터 이러한 수입을 모두 수행 할 필요는 없습니다. 예를 들어

Visualization.widgetbackref="visualizations"으로 정의된다는 사실은 Widget.visualizations이미 존재하는 것을 의미합니다 - 당신이 명시 적으로 만들 필요가 없습니다.

특별히 필요한 것이 많으면 많은 관계가 있습니다. 그러면 실제로 원하는 것은 define an association table for the many-to-many relationship입니다.

+0

답변 해 주셔서 감사합니다. 양방향 관계를 정의하려는 의도는 다음과 같습니다. – gyoho

+0

양방향 관계를 유지하겠다는 나의 의도에 대해 제 업데이트를 참조하십시오. 여기에 맞추기에는 너무 길다. 이 작업을 수행 할 올바른 방법이 있다면 알려주십시오. 또한 가져온 항목을 변경했지만 여전히 오류가 발생했습니다. 이것에 대한 업데이트도 참조하십시오. – gyoho

+0

@Abbwer'backref'는 멋지게 작동했습니다! ** Widget ** 클래스의 정의에서 ** Visualization ** 클래스를 사용할 필요가 없기 때문에 순환 가져 오기를 중단하는 ** Visualization ** 가져 오기를 제거 할 수 있습니다. 다시 한 번 감사드립니다! – gyoho