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))
我发现有信息表明,由于 sqlalchemyver. 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来做到这一点。 有机会这样做吗?
以防万一有人仍然坚持下去(就像我刚刚一样(,这里有一个相当简单的解决方案,对我有用。此方法通过解释缓存值 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