2012-02-23 10 views
2

複数のデータベースでelixirを使用しているsqlalchemyを使用しています。現在、すべてが複数のセッションでうまく動作します.1つは異なるデータベースにバインドされます。しかし、あるセッションを使用して別のデータベースに対してクエリを実行する場合があります(これは、異なるレプリケートされたデータベースを持つ複数のサーバーをサポートするためです)。sqlalchemyのデータベース名を含む修飾テーブル名

問題は、1つのセッションに対してクエリを作成するときに、テーブル名が適切なデータベース名で修飾されていないことと、どのデータベース名にプレフィックスを付けるかをクエリに伝えることができないことです。これを達成する方法はありますか?

答えて

1

これは、すでにすべてが異なるバインドの観点からマップされているため、難しい場合があります。表の "schema"引数は "schemaname.tablename"構文のレンダリング方法ですが、これはスキーマ名なしで表にマップされている通常のクラスとは異なるマッピングされたクラスを使用することを意味します。

このように、最初はいくつかのプラットフォーム固有のテクニックにより、これはずっと簡単になりました。 Oracleを使用している場合は、Oracle CREATE SYNONYMを使用して、リモート・スキーマの「somedb.sometable」を「sometable」にマップします。 Postgresqlを使用している場合は、search_pathを操作して、複数のスキーマで特定の名前が検索されるようにします(http://www.postgresql.org/docs/8.1/static/ddl-schemas.html#DDL-SCHEMAS-PATH参照)。

どちらも問題ありませんか?それでは、http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityNameでレシピの行に沿って何かする必要があります(残念ながら、これはエリクシールを使用していません。エリクシールの能力はどれくらいか分かりません)。詳細に応じて達成するためのさまざまな方法があります。ここでは、元のテーブルにマップされた新しい、匿名クラスを行います一つの方法です:

# regular class 
class ClassOne(Base): 
    __tablename__ = 'one' 
    id = Column(Integer, primary_key=True) 

class ClassTwo(Base): 
    __tablename__ = 'two' 
    id = Column(Integer, primary_key=True) 

def map_to_alt_tb(cls, metadata, schemaname): 
    m = class_mapper(cls) 
    cls2 = type(
     "AltClass", 
     (object,), 
     {} 
    ) 
    table = m.local_table.tometadata(metadata, schemaname) 
    mapper(cls2, table) 
    return cls2 

alt_cls = map_to_alt_db(ClassTwo, somemetadata, "alt_schema") 

map_to_alt_db()は、新しいにマップし、それは「alt_schema」へのスキーマです変更、ClassTwoがマッピングされるテーブルを引き出しますクラス。

しかし、このアプローチは、特別なものはどれもClassTwoで失われます。必要な場合は、そのwikiページにある特定のアプローチをさらに行うことができます。

2

Oracleと同様の問題がDBと同様に発生しました。スキーマ名はDBインスタンスによって異なりますので、これはあなたの状況に似ています。これを解決する方法は、最初にスキーマ・オブジェクトの所有者を決定するために、DBに単純なクエリを発射することであった

SELECT owner FROM ALL_OBJECTS WHERE object_name = :obj_name AND object_type = :obj_type 

その後、あなたの反射にスキーマパラメータの値として得られるスカラーを使用テーブル:

mytable = Table(name='my_table_name', 
       metadata=my_bound_metadata, 
       autoload=True, 
       schema=schema_owner) 
関連する問題