2012-06-27 12 views
6

SQLAlchemyにプライマリキーを持たないテーブルを作成することはできますか?次のように私が定義する関係は次のとおりです。あなたが見ることができるようにSQLAlchemyプライマリキーを持つ子テーブルを持たない1対多

class TPost(Base): 
    __tablename__ = "forum_post" 
    id = Column(Integer, primary_key = True) 
    topic_id = Column(Integer, ForeignKey("forum_topic.id")) 
    index = Column(Integer) 
    page = Column(Integer) 
    user_id = Column(Integer, ForeignKey("forum_user.id")) 
    posted_at = Column(DateTime) 
    post_text = Column(String) 
    has_quotes = Column(Boolean) 
    quotes = relationship("TQuote") 

class TQuote(Base): 
    __tablename__ = "forum_quotes" 
    id = Column(Integer, ForeignKey("forum_post.id")) 
    is_direct = Column(Boolean) 
    quoted_text = Column(String) 
    quoted_id = Column(Integer) 

は、私は本当に主キーを必要としない、と私は将来的にQuote関係を延長するつもりはありません。

私の問題は、具体的に、このエラーメッセージで表されます(引用は、直接ではないがとき、(id,quoted_id)ペアはユニークであり、データの大部分が存在 :

sqlalchemy.exc.ArgumentError: Mapper Mapper|TQuote|forum_quotes 
could not assemble any primary key columns for mapped table 'forum_quotes' 

編集その場合quoted_idはありません)、引用されたテキストを引用関係に直接インライン展開します。私はデュアルテーブルアプローチを使用することができます(ここでは、引用符で囲まれていないものはプライマリキーを持つテーブルを持っています)。しかし、これをむしろ単一の多対多関係として実装します。私は1回の参加以上のことをしたくありません。

編集2:

私は引用符を数とPKEY、まだ迷惑カントーとして外部キー+アプリ生成された番号を使用します。今すぐ構文を理解してください。

編集3:

のSQL錬金術とかなりイライラ編集2に概説されているようそれがハイレベルでデータをモデル化した場合でもrelatioshipを実装するために必要なすべての情報を持っているので、問題を解決しました。私は、Sql Alchemyが主キーを持っている理由を理解しています(ormを簡単に実装できます)。

なぜ私はSql Alchemyを使用しているのか疑問に思っています.SPSを使用しないと、psycopg2を使用してUPSERTまたはCREATE_IF_NOT_EXIST非同期操作を実装できます。 ORMは本当に追いつく必要があります。

+2

なぜあなたは1つを使用して抵抗しようとしていますか?それはサイズですか?データモデルのクリーン性?他の理由? – van

+0

主に清潔。しかし、シェアアライザを増やすことを考えると、別のデータベース操作です。 –

+0

はい、ただし、PKを定義しなくても、データベースは内部的に1つを保持し、同じ増分操作を実行します。PKの使用法は、すべてのRDBMSで最適化されています。 Googleが「サロゲートプライマリキー」を使用しているため、実際にはPKを必要としなくてもRDBをモデル化するのが最も簡単であるという結論に至るかもしれません。しかし、最も重要なのは、あなたがそれを持たないことで救うものは何もありません。パフォーマンス上の理由から、主に(id、quoted_id)を検索する場合は、PK列の代わりに(id、quoted_id)列にCLUSTED索引を定義することができます。 – van

答えて

1

は引用符にインデックスを与えるために追加の列を追加し、この新しい列+外部キーの複合キーを作成し追加します。

+0

あなたのソリューションを共有してくれてありがとう – van

13

私は、@ TokenMacGuyが正しいと仮定しています。あなたは実際にPrimaryKeysurrogate keyという概念を混同しています。その場合には、あなたの質問への答えは次のとおりです。

  • NO、SAは(テーブルにそのための関係)のテーブルをサポートしていない主キー
  • NOせずに、あなたが作成する必要はありません。 primary keyとして機能するための各テーブルの代理キー。一意の列を任意の組み合わせで使用してPKを定義できます。

例えば、以下のコードを参照してください:

class TPost(Base): 
    __tablename__ = 'forum_post' 
    id = Column(Integer, primary_key = True) 
    post_text = Column(String) 
    quotes = relationship("TQuote", backref="post") 

class TQuote(Base): 
    __tablename__ = "forum_quotes" 
    id = Column(Integer, ForeignKey("forum_post.id")) 
    is_direct = Column(Boolean) 
    quoted_text = Column(String) 
    quoted_id = Column(Integer) 
    __table_args__ = (PrimaryKeyConstraint(id, quoted_id),) 
+0

ありがとうございます。私は+1しました。 '(id、quoted_id)' = id_direct = trueの場合にのみ候補(データの75%がこのカテゴリに入ります)。したがって、すべてのデータの候補キーを取得するために、新しいフィールド+ idを使用しています。新しいフィールドは、インクリメントされた数値を生成するアプリケーションです。あなたの投稿を更新すれば、私は受け入れるでしょう< –

+1

私は質問に答えたと思いますが、改善する方法は見当たりません。問題をどのように解決したかについての追加のコメント(あなたが投稿したもの)とともに、それを受け入れるかどうかは自由です。または、独自のソリューションを追加して、完全性のために受け入れることもできます。 – van

関連する問題