1

나는이 내 술병/SQLAlchemy의 응용 프로그램에서 다음과 같은 네 가지 모델 클래스 (MyClassA은 참조를 여기에 표시 만되어 있지 않으며 다섯 번째 클래스) 다음 Flask-Migrate 명령 db init, db migratedb upgrade 작품 단지를 사용하여이 스키마를 만들기Flask/SQLAlchemy 모델에서이 순환 참조를 방지하는 방법은 무엇입니까?

class MyClassF(db.Model): 
    valid_fs = ['F1', 'F2'] 
    f_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    name = db.Column(db.Enum(*valid_fs, name='f_enum'), default='F1', nullable=False) 

class MyClassD(db.Model): 
    d_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    name = db.Column(db.String(128)) 
    v_collection = db.relationship('MyClassV', lazy='dynamic', backref=db.backref('d'), cascade='all, delete-orphan') 

class MyClassV(db.Model): 
    v_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    d_id = db.Column(db.Integer, db.ForeignKey(MyClassD.d_id), nullable=False) 
    c_collection = db.relationship('MyClassC', lazy='dynamic', backref=db.backref('v'), cascade='all, delete-orphan') 
    a_collection = db.relationship('MyClassA', lazy='dynamic', backref=db.backref('v'), cascade='all, delete-orphan') 

class MyClassC(db.Model): 
    c_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    v_id = db.Column(db.Integer, db.ForeignKey(MyClassV.v_id), nullable=False) 
    f_id = db.Column(
     db.Integer, 
     db.ForeignKey(MyClassF.f_id), 
     nullable=False, 
     #default=MyClassF.query.filter(MyClassF.name == "F1").one().f_id 
    ) 

벌금.

sqlalchemy.exc.InvalidRequestError: When initializing mapper Mapper|MyClassV|my_classV, expression 'MyClassC' failed to locate a name ("name 'MyClassC' is not defined"). If this is a class name, consider adding this relationship() to the class after both dependent classes have been defined.

내가 노력하고있어 모든 : 내가 선을 MyClassC.f_id의 정의를 해제 주석 및합니다 (migrations 디렉토리를 제거한 후) 다시 시도 할 때

그러나, 나는 다음과 같은 순환 종속성 오류가 MyClassC.f_id의 기본값이 MyClassF 테이블을 쿼리하여 설정되어 있는지 확인하십시오. 이 검사는 데이터베이스를 만들 때가 아니라 삽입 할 때 수행해야합니다. 그래서 왜 지금이 오류가 발생하는지 이해할 수 없습니다.

구현하려고하는 데이터베이스 무결성 규칙을 적용하는 동안 db.relationship() (또는 다른 기술)을 사용하여이 순환 종속성 오류를 해결하려면 어떻게해야합니까?

답변

3

기본 매개 변수는 SQL DEFAULT constraint으로 변환됩니다. AFAICT이 제한 조건은 삽입시 평가되지 않지만 표를 작성할 때 값이 기본값으로 사용됩니다 (즉, 표를 작성할 때 기본값이 한 번 설정되고 해당 열이없는 모든 행에 사용됨) 다른 테이블의 내용에 따라 동적으로 변경할 수 없습니다).

class MyClassC(db.Model): 
    c_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    v_id = db.Column(db.Integer, db.ForeignKey(MyClassV.v_id), nullable=False) 
    f_id = db.Column(
     db.Integer, 
     db.ForeignKey(MyClassF.f_id), 
     nullable=False, 
     default=lambda: MyClassF.query.filter(MyClassF.name == "F1").one().f_id 
    ) 

:

그러나 the documentation of SQLAlchemy는 기본 값으로 파이썬에서 기능을 통과 할 수 있으며 사용하기에 디폴트 값을 얻기 위해 각 삽입을 요구한다, 그래서 당신이 할 수 있다는 사실을 언급 그러나 이것은 이 아니며은 모든 데이터베이스 기능을 사용하여 기본값을 제공합니다. SQLAlchemy는 먼저 기본값을 가져 와서 쿼리에 수동으로 삽입합니다.

+0

완벽한 답변. 고맙습니다! –