0

サードパーティによって管理されている独自のデータベースにクエリを実行しています。データベースには、それぞれが多数のフィールドを持つ多くのテーブルがあります。

私の問題は、Tree、Site、Meterの3つの対象テーブルに関するものです。

ツリーテーブルは、単純なツリー構造でノードを記述します。他のデータとともに、それ自体の主キーを参照する外部キーがあります。Object_TypeフィールドとObject_IDフィールドもあります。SiteテーブルとMeterテーブルには、それぞれ多くのフィールドがあります。

ツリーノードは、メーターまたはサイトのいずれかと1対1の関係にあります。Object_Typeフィールドが1の場合、Object_IDフィールドはサイトテーブルの主キーを参照します。2の場合、メーターテーブルの主キーを参照します。

この例に従ってhttps://bitbucket.org/sqlalchemy/sqlalchemy/src/408388e5faf4/examples/declarative_reflection/declarative_reflection.py

私はリフレクションを使用してテーブル構造をロードしています

Base = declarative_base(cls=DeclarativeReflectedBase)

class Meter(Base):
    __tablename__ = 'Meter'

class Site(Base):
    __tablename__ = 'Site'

class Tree(Base):
    __tablename__ = 'Tree'
    Parent_Node_ID = Column(Integer, ForeignKey('Tree.Node_ID'))
    Node_ID = Column(Integer, primary_key=True)
    children = relationship("Tree", backref=backref('parent', remote_side=[Node_ID]))

Base.prepare(engine)

私は自己参照関係を含めましたが、それは完全に機能します。Object_Typeフィールドを適切にチェックして、外部キーとしてObject_IDを使用して2つの関係を追加するにはどうすればよいですか?

4

2 に答える 2

2

最初に反射についてのメモ。振り返りに頼らないほうがずっといいと思いました。

  1. コードをロード/操作するために有効なデータベース接続は必要ありません
  2. 暗黙的よりも明示的の方が優れているというPythonガイドに違反しています。コードを見ると、視野の外で魔法のように作成されるよりも、要素(列など)を見る方がよいでしょう。

これは、より多くのコードを意味しますが、より保守しやすくなります。

私が提案した理由は、少なくとも部分的には、あなたの投稿にスキーマが表示されないためです。

リフレクションに依存するのではなく、コードでテーブルとクラスを作成すると、マッピングをより適切に制御できます。

この場合、ポリモーフィックマッピングを使用します

  1. 上記のようにTreeNodeクラスを作成します。
  2. SiteNodeとMeterNodeをサブクラスとして作成します

コードには次のようなものが含まれます。

mapper(TreeNode,tree_table,polymorphic_on=tree_table.c.object_type)
mapper(SiteNode, site_table,inherits=TreeNode,
                 inherit_condition=site_table.c.node_id==tree_table.c.node_id,
                 polymorphic_identity=1)

お役に立てれば。

于 2012-07-09T20:28:27.587 に答える
1

tree.object_idをSiteまたはMeterのいずれかを参照できる外部キーにするには、SiteとMeterを共通のベーステーブルから派生させるか、結合されたテーブル継承にするか、同じテーブルにマップすることができます。単一テーブル継承、または誰かが言ったように、ツリーは2つの異なるテーブルと共通のベーステーブルにマップされます。この最後の提案は、TreeNodeにすでに「タイプ」フィールドがあるという考えとよく一致します。

より簡単な最後の代替方法は、TreeNodeで2つの外部キー(site_idとmeter_id)、および2つの関係「meter」と「site」を直接使用することです。次に、Python @propertyを使用して、どちらか一方を返します。

class TreeNode(Base):
   # ...

   @property
   def object(self):
       return self.meter or self.site
于 2012-07-11T17:02:52.120 に答える