繁体   English   中英

如何在 SQLAlchemy 中创建分区的 Oracle 表?

[英]How to create a Partitioned Oracle Table in SQLAlchemy?

在 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 文档中提到的水平/垂直分片,它在多个数据库上对数据进行分区。

这是一个很好的答案,感谢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
         )
     """
    }
)

我找不到一个很好的方法来做到这一点,但以下工作。 我已经将它用于分区表和制作外部表:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM