如何使用sqlalchemy orm将参数“缓存”的oracle序列设置为“无缓存”

时间:2019-10-01 08:18:47

标签: python oracle sqlalchemy

Python 3.7,Sqlalchemy 1.3.6,Oracle 12c。

如何使用Sqlalchemy ORM在Oracle中创建序列,并将参数CACHE设置为“ NO CACHE”。

例如,有一个由我准备的表类(arg ???可以是整数):

class Tests(BazaModel):
    _ _tablename_ _ = 'testtbl'
    testtbl_id = Column(Integer, Sequence('testseq', cache=???), primary_key=True)
    name = Column(String(51))

我发现自sqlalchemy ver. 1.1.12起可以使用arg缓存调用构造函数的信息,请参见以下示例:

__init__(name, start=None, increment=None, minvalue=None, maxvalue=None, nominvalue=None, nomaxvalue=None, cycle=None, schema=None, cache=None, order=None, optional=False, quote=None, metadata=None, quote_schema=None, for_update=False).
- cache

可选的整数值;预先计算的序列中将来值的数量。呈现Oracle和PostgreSQL可以理解的CACHE关键字。”

但是arg“ cache”接受值:无,大于1的整数,它们当然都不产生我想要的值。

此刻,我不想在数据库上显式调用原始sql来更改序列设置,就像这样:

CREATE SEQUENCE  "xxx_APP"."testseq"  MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOCACHE  NOORDER  NOCYCLE;

我想使用Sqlalchemy ORM做到这一点。 有机会这样做吗?

1 个答案:

答案 0 :(得分:2)

以防万一有人仍然坚持这个(就像我一样),这里有一个对我有用的相当简单的解决方案。这种方法通过解释缓存值 0 或 1 来使用 NOCACHE 选项来调整生成的 SQL。我同意关于是否通常需要的评论,但我只是发现每天添加的东西每天增加 20 很烦人!该技术适用于 Oracle 中其他 SQL 自定义。

# Change this for your own connection
user, pwd, host, service = "USER", "PWD", "HOST", "SERVICE"

# START OF SPECIAL CODE >>>
from sqlalchemy.schema import CreateSequence
from sqlalchemy.ext.compiler import compiles

@compiles(CreateSequence, "oracle")
def visit_create_sequence(element, compiler, **kw):
    """ 
    Modify create sequence for Oracle to support NOCACHE, by 
    translating a cached number of 0 or 1 into NOCACHE 
    """
    nocache = element.element.cache in {0, 1}
    if nocache:
        element.element.cache = None
    sql = compiler.visit_create_sequence(element, **kw)
    if nocache:
        sql += " NOCACHE"
    return sql
# <<< END OF SPECIAL CODE

# Now on with creating the sequence
from sqlalchemy import create_engine, MetaData, Sequence
conn_str = f"oracle+cx_oracle://{user}:{pwd}@{host}:1521/?service_name={service}"
engine = create_engine(conn_str)
metadata = MetaData(engine)
test_seq = Sequence('test_seq', metadata=metadata, cache=1)
metadata.create_all(bind=engine)

结果序列如下所示:

select dbms_metadata.get_ddl('SEQUENCE', 'TEST_SEQ') from dual;
CREATE SEQUENCE  "USER"."TEST_SEQ"  MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOCACHE  NOORDER  NOCYCLE  NOKEEP  NOSCALE  GLOBAL