2017-03-23 29 views
0

In Oracle we can create a partitioned tableSQLAlchemyでパーティション化されたOracleテーブルを作成するには?次のような

 
CREATE TABLE sales_hash 
    (s_productid NUMBER, 
    s_saledate DATE, 
    s_custid  NUMBER, 
    s_totalprice NUMBER) 
PARTITION BY HASH(s_productid) 
(PARTITION p1 TABLESPACE tbs1 
, PARTITION p2 TABLESPACE tbs2 
, PARTITION p3 TABLESPACE tbs3 
, PARTITION p4 TABLESPACE tbs4 
); 

は、それはSQLAlchemyのを介してこれを行うことは可能ですか?

複数のデータベースにデータを分割するSQLAlchemyのドキュメントhereに記載されている水平/垂直シャーディングについては言及していません。

答えて

0

が優れた答えである、Mike Byer

 

from sqlalchemy import MetaData, Column, String, create_engine 
from sqlalchemy.ext.declarative import declarative_base 

from sqlalchemy.schema import CreateTable 
from sqlalchemy.ext.compiler import compiles 
import textwrap 


@compiles(CreateTable, "oracle") 
def _add_suffixes(element, compiler, **kw): 
    text = compiler.visit_create_table(element, **kw) 
    if "oracle_partition" in element.element.info: 
     text += textwrap.dedent(
      element.element.info["oracle_partition"]).strip() 
    return text 

# use mock strategy just to illustrate this w/o my getting 
# on an oracle box 
def execute_sql(stmt): 
    print stmt.compile(dialect=engine.dialect) 
engine = create_engine("oracle://", execute_sql, strategy="mock") 


metadata = MetaData() 
Base = declarative_base(metadata=metadata) 
class Foo(Base): 
    __tablename__ = 'foo' 
    name = Column(String(10), primary_key=True) 
    __table_args__ = { 
     'info': { 
      'oracle_partition': """ 
       PARTITION BY HASH(name) 
       (PARTITION p1 TABLESPACE tbs1 
       , PARTITION p2 TABLESPACE tbs2 
       , PARTITION p3 TABLESPACE tbs3 
       , PARTITION p4 TABLESPACE tbs4 
       ) 
      """ 
     } 
    } 

Foo.__table__.create(bind=engine) 

のおかげで、古典的な使い方:

 
m = MetaData() 
t = Table(
    'sales_hash', m, 
    Column('s_productid', NUMBER), 
    Column('s_saledate', DATE), 
    Column('s_custid', NUMBER), 
    Column('s_totalprice', NUMBER), 
    info={ 
    "oracle_partition": """ 
     PARTITION BY HASH(s_productid) 
     (PARTITION p1 TABLESPACE tbs1 
     , PARTITION p2 TABLESPACE tbs2 
     , PARTITION p3 TABLESPACE tbs3 
     , PARTITION p4 TABLESPACE tbs4 
     ) 
    """ 
    } 
) 
0

いい方法がありませんでしたが、以下のように動作します。私は両方のパーティションテーブルのためにそれを使用して外部表を作成しました:ここ

 
import sqlalchemy 
from sqlalchemy.dialects import oracle 


append_partition_ddl = ''' 
PARTITION BY HASH(s_productid) 
(PARTITION p1 TABLESPACE tbs1 
, PARTITION p2 TABLESPACE tbs2 
, PARTITION p3 TABLESPACE tbs3 
, PARTITION p4 TABLESPACE tbs4 
) 
''' 

engine = sqlalchemy.create_engine(con_str) 

# This will get populated with all the DDLs used to create the table 
# E.g., the CREATE TABLE, CREATE SEQUENCE, and etc 
ddls = [] 

def capture_ddl(sql): 
    """The mock executor will capture the DDL statement and add it to ddls""" 
    ddl = str(sql.compile(dialect=oracle.dialect())) 
    ddls.append(ddl) 

mock_engine = sqlalchemy.create_engine(engine.url, 
    strategy='mock', 
    executor=lambda sql, *multiparams, **params: capture_ddl(sql)) 

# This doesn't actually execute any DDL, but generates a mock DDL 
my_table.create(bind=mock_engine) 

real_table_ddl = ''.join([ddls[0], append_partition_dll]) 

# Use the real engine to execute the DDLs 
engine.execute(real_table_ddl) 

関連する問題