2013-07-19 6 views
14

FlaskでSQLAlchemyを使用して、アプリケーションのリレーションシップを作成しています。私のモデルでSQL Alchemyで私の関係に何が問題になっていますか?

sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between 
parent/child tables on relationship CurriculumVersion.enrollments - there are 
no foreign keys linking these tables. Ensure that referencing columns are 
associated with a ForeignKey or ForeignKeyConstraint, or specify 
a 'primaryjoin' expression. 

class User(db.Model, AuthUser): 
    id = db.Column(db.Integer, primary_key=True) 
    tf_login = db.Column(db.String(255), unique=True, nullable=False) # can assume is an email 
    password = db.Column(db.String(120), nullable=False) 
    salt = db.Column(db.String(80)) 
    role = db.Column(db.String(80)) # for later when have different permission types 
    zoho_contactid = db.Column(db.String(20), unique=True, nullable=False) 
    created_asof = db.Column(db.DateTime, default=datetime.datetime.utcnow) 
    enrollments = db.relationship('Enrollment', backref='enrollment', lazy='dynamic') 
    firstname = db.Column(db.String(80)) 
    lastname = db.Column(db.String(80)) 


    def __repr__(self): 
     return '#%d tf_login: %s, First Name: %s Last Name: %s created_asof %s' % (self.id, self.tf_login, self.firstname, self.lastname, self.created_asof) 

    def __getstate__(self): 
     return { 
      'id': self.id, 
      'tf_login': self.tf_login, 
      'firstname': self.firstname, 
      'lastname': self.lastname, 
      'role': self.role, 
      'created_asof': self.created_asof, 
     } 

    @classmethod 
    def load_current_user(cls, apply_timeout=True): 
     data = get_current_user_data(apply_timeout) 
     if not data: 
      return None 
     return cls.query.filter(cls.email==data['email']).one() 
     return '#%d Course Name: %s, Course Version: %s, Closing Date: %s' %(self.id, self.course_name, self.course_version, self.closing_date) 

class Enrollment(db.Model, AuthUser): 
    id = db.Column(db.Integer, primary_key=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id')) 
    version_id = db.Column(db.Integer, db.ForeignKey('curriculumversion.id')) 
    cohort_id = db.Column(db.Integer, db.ForeignKey('cohort.id')) 

    def __repr__(self): 
     return '#%d User ID: %d Version ID: %d, Cohort ID: %d' %(self.id, self.user_id, self.version_id, self.cohort_id) 

class Cohort(db.Model, AuthUser): 
    id = db.Column(db.Integer, primary_key=True) 
    days_to_completion = db.Column(db.String(20)) 
    course_id = db.Column(db.Integer, db.ForeignKey('course.id')) 
    enrollments = db.relationship('Enrollment', backref='enrollment', lazy='dynamic') 

    def __repr__(self): 
     return '#%d Days To Completion: %s' %(self.id, self.days_to_completion) 


class CurriculumVersion(db.Model, AuthUser): 
    id = db.Column(db.Integer, primary_key=True) 
    version_number = db.Column(db.String(6)) 
    date_implemented = db.Column(db.DateTime) 
    course_id = db.Column(db.Integer, db.ForeignKey('course.id')) 
    enrollments = db.relationship('Enrollment', backref='enrollment', lazy='dynamic') 

    def __repr__(self): 
     return '#%d Version Number: %s, Date Implemented: %s' %(self.id, self.version_number, self.date_implemented) 

class Course(db.Model, AuthUser): 
    id = db.Column(db.Integer, primary_key=True) 
    course_code = db.Column(db.String(20)) 
    course_name = db.Column(db.String(50)) 
    versions = db.relationship('CurriculumVersion', backref='version', lazy='dynamic') 
    cohorts = db.relationship('Cohort', backref='cohort', lazy='dynamic') 


    def __repr__(self): 
     return '#%d Course Code: %s, Course Name: %s' %(self.id, self.course_code, self.course_name) 

任意の助けをいただければ幸い私は最近、関係なく、私が変更何、私はエラーを取得維持しない、関係を書き直し、そして!

変更

enrollments = db.relationship('Enrollment', backref='enrollment', lazy='dynamic') 

enrollments = db.relationship('Enrollment', backref='enrollment', lazy='dynamic', primaryjoin="Enrollment.version_id==CurriculumVersion.id") 

への注意:あなたは、他のクラスのためにこれを実行する必要があるかもしれませんが、次のようにあなたのCurriculumVersionクラスでprimaryjoin使用する

答えて

26

このエラーは:

Could not determine join condition between parent/child tables on relationship CurriculumVersion.enrollments 

SQLAlchemyのは、関係の外部キーとして使用するEnrollmentsに適切な列を見つけることができなかったことを意味します。

外部キーを定義しましたが、間違ったテーブル名を使用しました。これに

class Enrollment(db.Model, AuthUser): 
    # ... 
    version_id = db.Column(db.Integer, db.ForeignKey('curriculumversion.id')) 
    #... 

:表の作成時にフラスコSQLAlchemyのは、あなたがこれを変更する必要があるので、camel_caseCamelCaseクラスを変換

class Enrollment(db.Model, AuthUser): 
    # ... 
    version_id = db.Column(db.Integer, db.ForeignKey('curriculum_version.id')) 
    #... 

代わりにデフォルトの命名規則を上書きする__tablename__属性を使用することができますFlask-SQLAlchemyで使用されます。

+0

これは本当に私を怒らせた。それがなぜそれをするのか? –

+2

Flaskは、開発者が明示的にこれらの規則を作成するのではなく、あなたの名前を作成すると思っているので、人生が楽になります。 SQLAlchemy自体は、いかなる種類の慣習も決して生成しないようになっています。あなた自身で作成するツールを提供するだけです。 – zzzeek

2

してみてください。

+0

"sqlalchemy.exc.NoReferencedTableError:列 'enrollment.version_id'に関連付けられている外部キーが列 'id'を対象とする外部キーを生成する 'CurriculumVersion'テーブルを見つけることができませんでした。アイデア? –

+0

この例ではForeignKeyは 'curriculumversion.id'を参照していますが、なんらかの理由で「CurriculumVersion」という名前のテーブルを探しています.db.Modelは正確に何をしますか、 '__tablename__'はどこですか?など? – zzzeek

関連する問題