2017-08-19 18 views
0

更新:。完全に動作するコードサンプルがhereある)SQLAlchemyのとあいまいなのForeignKey

class City(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(32), index=True) 
    country_id = db.Column(db.Integer, db.ForeignKey('country.id')) 
    country = db.relationship('Country', back_populates='cities') 

class Country(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(32), index=True) 
    cities = db.relationship('City', back_populates='country') 

は、多くの中から1つを区別することによってaugmentedすることができ、このMany-To-One関係は、首都として言います。

これらの二つの溶液のうち

、別のテーブルを追加すること

class Capital(db.Model): 
    # https://stackoverflow.com/q/45767923/8099646 
    id = db.Column(db.Integer, primary_key=True) 
    country = db.Column(db.Integer, db.ForeignKey('country.id')) 
    capital = db.Column(db.Integer, db.ForeignKey('city.id')) 

実現可能であるが、よりよい解決策は、余分なテーブルを回避し、単にフィールドを挿入することです:

class Country(db.Model): 
    ... 
    capital = db.Column(db.Integer, db.ForeignKey('city.id')) 

なぜSQLAlchemyのは、文句を言うんAmbiguousForeignKeysErrorその行が追加されたら?二つの可能性(すなわちcountry_idcapital)があるため、

答えて

1

理由が今SQLAlchemyのは、結合条件を知りませんcountry/cities関係がを指しています。

この問題を解決する方法は明示的foreign_keysを指定することである:円形パターンのこの種はまた、テーブルを作成するときに(それぞれが他なしで作成することができないため)CircularDependencyErrorもたらすとなること

class City(db.Model): 
    ... 
    country = db.relationship('Country', foreign_keys=country_id, back_populates='cities') 

class Country(db.Model): 
    ... 
    cities = db.relationship('City', foreign_keys=City.country_id, back_populates='country') 

注2つの相互依存関係で挿入する(各行は他の行のIDなしで挿入できないため)。したがって、ForeignKey(サイクルを中断するためにテーブルを作成するときにALTERを発行する)と、relationshipのいずれかにpost_update(サイクルを中断するために挿入するときにUPDATEを発行する)のいずれかにuse_alterを設定することです):

class City(db.Model): 
    ... 
    country_id = db.Column(db.Integer, db.ForeignKey('country.id')) 
    country = db.relationship('Country', foreign_keys=country_id, back_populates='cities') 

class Country(db.Model): 
    ... 
    capital_id = db.Column(db.Integer, db.ForeignKey('city.id', use_alter=True)) 
    capital = db.relationship(City, foreign_keys=capital_id, post_update=True) 
    cities = db.relationship(City, foreign_keys=City.country_id, back_populates='country') 
+0

私はあなたが私の知る限りでは死角を指摘しているように感じます。私は参照を追求することができますいくつかのキーワードを言及できますか?もっと読むには、教科書のデータベースの文献(リレーショナルデータベース)、SQLの仕組み(SQLの錬金術以外)、特にSQLの錬金術を見てみましょう。 – Sebastian

+0

@セバスチャン私があなたが知らないことを知らないので、その質問に答えるのは難しいですが、私はあなたが深い理解を得たいかもしれないいくつかのことを言及します:1.外部キーを使って関係をモデル化する方法SQLのみを使用します。 2.外部キーを介して互いに参照する2つのテーブルを持つ 'CREATE TABLE'(なぜ、' ALTER'なしでは不可能です)。 3.外部キーを使用して互いに参照する自動インクリメント主キーを持つ 'INSERT' 2行(なぜ、それが' UPDATE'なしでは不可能です)。 4. http://docs.sqlalchemy.org/en/latest/core/exceptions.html#sqlalchemy.exc.CircularDependencyError – univerio

関連する問題