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做到这一点。 有机会这样做吗?
答案 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