【问题标题】:Qualifying table names with database names in sqlalchemy在 sqlalchemy 中使用数据库名称限定表名
【发布时间】:2012-02-24 01:01:32
【问题描述】:

我在多个数据库上使用带有 elixir 的 sqlalchemy。目前一切都适用于多个会话 - 一个绑定到不同的数据库。但是,在某些情况下,我想使用一个会话来查询另一个数据库(这是为了支持具有不同复制数据库的多个服务器)。

问题是,当对一个会话进行查询时,表名没有用正确的数据库名称限定,我不知道如何告诉查询以哪个数据库名称为前缀。有没有办法做到这一点?

【问题讨论】:

    标签: python database sqlalchemy


    【解决方案1】:

    在使用 Oracle 时遇到了与数据库类似的问题。数据库实例之间的架构名称不同,因此希望这与您的情况类似。

    解决此问题的方法是首先向数据库发起一个简单查询以确定架构对象的所有者:

    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)
    

    【讨论】:

      【解决方案2】:

      这可能很困难,因为您已经根据不同的绑定映射了所有内容。 Table 的“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 的配方做一些事情(对不起,这不是使用 Elixir,我不确定 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 页面上的更多特定方法。

      【讨论】:

        猜你喜欢
        • 2018-01-10
        • 2020-02-14
        • 1970-01-01
        • 2018-09-09
        • 1970-01-01
        • 2020-12-11
        • 2011-05-15
        • 2021-12-28
        • 2020-02-27
        相关资源
        最近更新 更多