2012-02-23 26 views
2

我在多個數據庫上使用sqlalchemy和elixir。目前,一切都適用於多個會話 - 一個綁定到不同的數據庫。但是,有些情況下我想使用一個會話來查詢其他數據庫(這是爲了支持具有不同複製數據庫的多個服務器)。在sqlalchemy中使用數據庫名稱限定表名

問題是,當針對一個會話進行查詢時,表名未使用正確的數據庫名稱限定,我不知道如何告訴查詢要將哪個數據庫名稱作爲前綴。有什麼辦法可以做到這一點?

回答

1

這可能很困難,因爲您已經根據不同的綁定映射了所有內容。 Table的「模式」參數是如何呈現「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的配方上做些事情(對不起,這不是使用藥劑,我不確定Elixir的能力是如何)。取決於具體情況,有不同的方法來實現它。這裏有一種方法,這將使映射到原來的表一個新的,匿名類:

# 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()將拉出表ClassTwo映射到,改變它的模式改爲「alt_schema」,然後將其映射到一個新的類。

雖然這種方法失去了其他特別的東西ClassTwo。如果你需要的話,你可以在Wiki頁面上做更多的特定方法。

2

與Oracle遇到了與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) 
相關問題