1

私は最近、Pylons を使っていくつかの作業を行っていますが、データベースの相互作用のための SQLAlchemy モデルが非常に気に入っています。私の Web サイトには、EAV スキーマの恩恵を受けると思われるセクションが 1 つあります。

これを私のテーブルの例として使用します:

id | userid | type   | value
---+--------+--------|------------
1  |  1     |  phone | 111 111 111
---+--------+--------|------------
2  |  1     |  age   | 40

次のようなクエリを手動で実行して、データを抽出および更新できます。

SELECT value FROM table WHERE userid=1 AND type='phone'
UPDATE table SET value=41 WHERE userid=1 AND type='age'

それは簡単で機能します...しかし、手動でクエリを作成することは、私の好みのアプローチではありません。SQLAlchemy を使用してテーブル モデルを作成し、すべての処理を実行させたいと考えています。

それぞれtypeに独自の列がある標準スキーマを使用する場合、次のことができます。

class People(Base):

   __tablename__ = 'people'

   id      = Column(Integer, primary_key=True)
   userid  = Column(Integer, ForeignKey('users.id'))
   phone   = Column(Unicode(40))
   age     = Column(Integer)

次に、次を使用してデータを引き出すことができます。

data = Session.query(People).filter_by(id=1).first()
print data.age

EAV スキーマでも同じことができるようにしたいと考えています。data.ageしたがって、基本的には、SQLAlchemy を拡張して、それを実際に呼び出すと、 が必要であることを伝える方法が必要ですSELECT value FROM table WHERE id=1 AND type='age'

これは実行可能ですか?または、手動で発行されたクエリでコードを乱雑にする必要がありますか?

4

1 に答える 1

6

垂直属性マッピングの例を見てください。これは多かれ少なかれあなたが求めているものだと思います。例では、例のように属性ではなく、dict のようなインターフェイスを示しています (おそらく、いくつかの特定の属性ではなく、任意のメタデータ キーの方が適しています)。

各属性を個別にマップしたい場合: 興味のあるドキュメントの内容:

  • マップされた属性としてのSQL式:実際に属性を任意のSQL式にマップする方法(読み取り専用)
  • 属性の動作の変更、特に。記述子とカスタム コンパレータの使用: これは、属性に通常の python プロパティを使用し、get/set で必要なことを実行し、オプションで他の値 (クエリ用) との比較がどのように機能する必要があるかを規定することになります。
  • associationproxy : 基本的に、関係に関するより単純なビューを提供します。たとえば、あなたのケースでは_age、カスタム結合条件(ユーザーIDだけでなく、タイプ「年齢」も指定)を使用して、KeyValue(またはそれを呼び出したいもの)との関係を作成できます(uselist=False存在するため)ユーザーごとに 1 つの年齢のみ、リストではなく単一の値が必要です)。age = association_proxy('_age', 'value')次に、 KeyValue オブジェクト全体ではなく、値のみを「表示」するために使用できます。

垂直属性マッピングの例に基づいたものか、associationproxy/ のいずれかを使用すると思います。

于 2010-08-03T14:24:47.140 に答える