Support for the Oracle database.
The following table summarizes current support levels for database release versions.
Support type |
Versions |
---|---|
11.2, 18c |
|
11+ |
|
8+ |
The following dialect/DBAPI options are available. Please refer to individual DBAPI sections for connect information.
通常假定包含整数主键的SQLAlchemy表对象具有“自动递增”行为,这意味着它们可以在插入时生成自己的主键值。对于在Oracle中使用,有两个选项可用,即使用标识列(仅限Oracle 12及更高版本)或序列与列的关联。
从版本12开始,Oracle可以使用 Identity
要指定自动递增行为:
t = Table('mytable', metadata,
Column('id', Integer, Identity(start=3), primary_key=True),
Column(...), ...
)
上面的创建表 Table
对象为:
CREATE TABLE mytable (
id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 3),
...,
PRIMARY KEY (id)
)
这个 Identity
对象支持许多选项来控制列的“自动递增”行为,如起始值、递增值等。除了标准选项外,Oracle还支持设置 Identity.always
到 None
要使用默认的生成模式,在DDL中呈现为IDENTITY。它还支持设置 Identity.on_null
到 True
将ON NULL与“默认”标识列一起指定。
旧版本的Oracle没有“autoincrement”特性,SQLAlchemy依赖序列来生成这些值。对于较旧的Oracle版本, 必须始终显式指定序列才能启用自动增量 . 这与大多数文档示例不同,这些文档示例假定使用具有自动增量功能的数据库。要指定序列,请使用传递给列构造的sqlachemy.schema.sequence对象::
t = Table('mytable', metadata,
Column('id', Integer, Sequence('id_seq'), primary_key=True),
Column(...), ...
)
使用表反射时也需要此步骤,即AUTLOAD_WITH=ENGINE::
t = Table('mytable', metadata,
Column('id', Integer, Sequence('id_seq'), primary_key=True),
autoload_with=engine
)
Oracle数据库支持“READ COMMITTED”和“SERIALIZABLE”隔离模式。CX_ORACLE方言也支持AUTOCOMMIT隔离级别。
使用每个连接执行选项进行设置:
connection = engine.connect()
connection = connection.execution_options(
isolation_level="AUTOCOMMIT"
)
为 READ COMMITTED
和 SERIALIZABLE
,Oracle方言使用以下命令在会话级别设置级别 ALTER SESSION
,当连接返回到连接池时,它将恢复为其默认设置。
的有效值 isolation_level
包括:
READ COMMITTED
AUTOCOMMIT
SERIALIZABLE
注解
的实现 Connection.get_isolation_level()
由Oracle方言实现的方法必须使用Oracle LOCAL_TRANSACTION_ID函数强制启动事务;否则没有任何级别通常是可读的。
此外, Connection.get_isolation_level()
方法将引发异常,如果 v$transaction
由于权限或其他原因,视图不可用,这在Oracle安装中很常见。
CX_ORACLE方言尝试调用 Connection.get_isolation_level()
当方言首次连接到数据库以获取“默认”隔离级别时,调用。此缺省级别是必需的,以便在使用临时修改连接后可以在连接上重置该级别 Connection.execution_options()
方法。在常见情况下, Connection.get_isolation_level()
方法引发异常,原因是 v$transaction
由于不可读以及任何其他与数据库相关的故障,该级别被假定为“已提交读取”。对于此初始首次连接条件不会发出警告,因为预计这将是Oracle数据库的常见限制。
1.3.16 新版功能: 向cx_oracle方言添加了对AUTOCOMMIT的支持以及默认隔离级别的概念
1.3.21 新版功能: 添加了对SERIALIZABLE以及隔离级别实时读取的支持。
在 1.3.22 版更改: 在Oracle安装中常见的由于v$TRANSACTION视图上的权限而导致默认隔离级别无法读取的情况下,默认隔离级别被硬编码为“READ COMMITTED”,这是1.3.21之前的行为。
在Oracle中,数据字典使用大写文本表示所有不区分大小写的标识符名称。另一方面,SQLAlchemy认为所有小写标识符名称都不区分大小写。在模式级通信期间,Oracle方言将所有不区分大小写的标识符转换为这两种格式,例如表和索引的反射。在sqlAlchemy端使用大写名称表示区分大小写的标识符,sqlAlchemy将引用该名称-这将导致与从Oracle接收的数据字典数据不匹配,因此,除非标识符名称真正创建为区分大小写(即使用带引号的名称),否则所有小写名称都应在sqlAlchemy上使用。一边。
自Oracle Server 12.2版起,Oracle已更改默认的最大标识符长度。在这个版本之前,长度是30,对于12.2及更高版本,现在是128。此更改会影响生成的SQL标签名称区域中的SQLAlchemy以及约束名称的生成,尤其是在中描述的约束命名约定功能的情况下 配置约束命名约定 正在被使用。
为了帮助进行此更改和其他更改,Oracle包含了“兼容性”版本的概念,它是一个独立于实际服务器版本的版本号,以帮助迁移Oracle数据库,并且可以在Oracle服务器本身中进行配置。使用此版本检索兼容性 SELECT value FROM v$parameter WHERE name = 'compatible';
. SQLAlchemy Oracle方言负责确定默认的最大标识符长度时,将在第一次连接时尝试使用此查询,以确定服务器的有效兼容性版本,该版本确定服务器允许的最大标识符长度。如果表不可用,则使用服务器版本信息。
从SQLAlchemy 1.4开始,Oracle方言的默认最大标识符长度为128个字符。第一次连接时,将检测到兼容版本,如果兼容版本低于Oracle 12.2版,则最大标识符长度将更改为30个字符。在所有情况下,设置 create_engine.max_identifier_length
参数将绕过此更改,给定的值将按原样使用:
engine = create_engine(
"oracle+cx_oracle://scott:tiger@oracle122",
max_identifier_length=30)
在SELECT语句中生成匿名SQL标签时,最大标识符长度都会发挥作用,但在根据命名约定生成约束名称时更为关键。正是这个区域使得SQLAlchemy需要保守地更改这个默认值。例如,以下命名约定根据标识符长度生成两个截然不同的约束名称:
from sqlalchemy import Column
from sqlalchemy import Index
from sqlalchemy import Integer
from sqlalchemy import MetaData
from sqlalchemy import Table
from sqlalchemy.dialects import oracle
from sqlalchemy.schema import CreateIndex
m = MetaData(naming_convention={"ix": "ix_%(column_0N_name)s"})
t = Table(
"t",
m,
Column("some_column_name_1", Integer),
Column("some_column_name_2", Integer),
Column("some_column_name_3", Integer),
)
ix = Index(
None,
t.c.some_column_name_1,
t.c.some_column_name_2,
t.c.some_column_name_3,
)
oracle_dialect = oracle.dialect(max_identifier_length=30)
print(CreateIndex(ix).compile(dialect=oracle_dialect))
如果标识符长度为30,则上面的CREATE INDEX如下所示:
CREATE INDEX ix_some_column_name_1s_70cd ON t
(some_column_name_1, some_column_name_2, some_column_name_3)
但是,当长度=128时,它变为:
CREATE INDEX ix_some_column_name_1some_column_name_2some_column_name_3 ON t
(some_column_name_1, some_column_name_2, some_column_name_3)
因此,在Oracle server 12.2版或更高版本上运行SQLAlchemy 1.4之前版本的应用程序将面临数据库迁移的情况,即希望对以前生成的较短长度的名称“删除约束”。当标识符长度更改而不首先调整索引或约束的名称时,此迁移将失败。强烈建议此类应用程序利用 create_engine.max_identifier_length
为了保持对截断名称生成的控制,并在更改此值时全面检查和测试登台环境中的所有数据库迁移,以确保已减轻此更改的影响。
在 1.4 版更改: Oracle的默认最大标识符长度为128个字符,如果检测到旧版本的Oracle server(兼容版本<12.2),则在第一次连接时将其调整为30个字符。
直到12c版,Oracle才对LIMIT和OFFSET提供直接支持。为了在从8系列开始的所有广泛使用的Oracle版本中实现这种行为,SQLAlchemy当前使用ROWNUM来实现LIMIT/OFFSET;准确的方法来自https://blogs.oracle.com/oraclemagazine/on-rownum-and-limiting-results.
当前只有一个选项可以影响其行为:
默认情况下不使用“FIRST_ROWS()”优化关键字。要启用此优化指令的使用,请指定 optimize_limits=True
到 create_engine()
.
在 1.4 版更改: Oracle方言使用“后编译”方案呈现限制/偏移整数值,该方案在将语句传递给游标执行之前直接呈现整数。这个 use_binds_for_limits
旗帜不再有效。
支持更改行号策略,其中包括一个使用 row_number()
窗口函数以及使用oracle12c“FETCH FIRST N ROW/OFFSET N ROWS”关键字的函数可能会在将来的版本中添加。
Oracle数据库支持有限的返回形式,以便从insert、update和delete语句中检索匹配行的结果集。Oracle的返回..in to语法只支持返回一行,因为它依赖out参数才能运行。此外,受支持的DBAPI还有进一步的限制(请参见 返回支持 )
SQLAlchemy的“隐式返回”功能通常在Oracle后端启用,它使用在insert中返回,有时还使用update语句来获取新生成的主键值和其他SQL默认值和表达式。默认情况下,“隐式返回”通常只获取单个 nextval(some_seq)
嵌入到insert中的表达式,以便在insert语句中增加序列并同时返回值。要全面禁用此功能,请指定 implicit_returning=False
到 create_engine()
::
engine = create_engine("oracle://scott:tiger@dsn",
implicit_returning=False)
隐式返回也可以作为表选项逐个表禁用:
# Core Table
my_table = Table("my_table", metadata, ..., implicit_returning=False)
# declarative
class MyClass(Base):
__tablename__ = 'my_table'
__table_args__ = {"implicit_returning": False}
参见
返回支持 -对隐式返回的其他cx_Oracle特定限制。
Oracle没有原生更新时级联功能。https://asktom.oracle.com/tkyte/update_cascade/index.html上提供了基于触发器的解决方案。
使用SQLAlchemy ORM时,ORM手动发出级联更新的能力有限-使用“deferrable=true,initially='deferred'”关键字参数指定foreignkey对象,并在每个关系()上指定“passive_updates=false”。
当检测到Oracle 8时,方言在内部将自身配置为以下行为:
当对表对象使用反射时,方言可以通过传递标志来选择性地搜索由同义词表示的表,无论是在本地模式还是远程模式中,还是通过dblink访问的表。 oracle_resolve_synonyms=True
作为关键字参数 Table
结构:
some_table = Table('some_table', autoload_with=some_engine,
oracle_resolve_synonyms=True)
设置此标志时,给定的名称(例如 some_table
将不仅仅在 ALL_TABLES
视图,但也在 ALL_SYNONYMS
查看此名称是否实际上是其他名称的同义词。如果同义词位于并引用dblink,则Oracle方言知道如何使用dblink语法(例如 @dblink
)
oracle_resolve_synonyms
在接受反射参数的地方接受,包括 MetaData.reflect()
和 Inspector.get_columns()
.
如果同义词未使用,则应禁用此标志。
Oracle方言可以返回有关外键、唯一和检查约束以及表上索引的信息。
有关这些约束的原始信息可以使用 Inspector.get_foreign_keys()
, Inspector.get_unique_constraints()
, Inspector.get_check_constraints()
和 Inspector.get_indexes()
.
在 1.2 版更改: Oracle方言现在可以反映唯一和检查约束。
使用反射时 Table
水平 Table
还将包括这些约束。
注意以下注意事项:
当使用 Inspector.get_check_constraints()
方法,Oracle为指定“not null”的列生成一个特殊的“is not null”约束。这个约束是 not 默认情况下返回;要包含“is not null”约束,请传递标志 include_all=True
::
from sqlalchemy import create_engine, inspect
engine = create_engine("oracle+cx_oracle://s:t@dsn")
inspector = inspect(engine)
all_check_constraints = inspector.get_check_constraints(
"some_table", include_all=True)
在大多数情况下,当反映 Table
,唯一约束将 not 可作为 UniqueConstraint
对象,因为在大多数情况下,Oracle使用唯一索引来镜像唯一约束(当两个或多个唯一约束表示同一列时似乎是例外); Table
而是用 Index
与 unique=True
标志集。
Oracle为表的主键创建隐式索引;此索引是 排除 从所有索引结果。
为索引反映的列列表将不包括以sys_nc开头的列名称。
这个 Inspector.get_table_names()
和 Inspector.get_temp_table_names()
方法分别返回当前引擎的表名列表。这些方法也是操作中发生的反射的一部分,例如 MetaData.reflect()
. 默认情况下,这些操作不包括 SYSTEM
和 SYSAUX
操作中的表空间。为了更改此设置,可以在引擎级别使用 exclude_tablespaces
参数::
# exclude SYSAUX and SOME_TABLESPACE, but not SYSTEM
e = create_engine(
"oracle://scott:tiger@xe",
exclude_tablespaces=["SYSAUX", "SOME_TABLESPACE"])
1.1 新版功能.
Oracle没有已知的数据类型 DATETIME
相反,它只有 DATE
,它实际上可以存储日期和时间值。因此,Oracle方言提供了 DATE
它是 DateTime
. 此类型没有特殊行为,并且仅作为此类型的“标记”存在;此外,当数据库列被反映并且该类型被报告为 DATE
,时间支持 DATE
使用类型。
create table短语与Oracle一起支持以下选项 Table
构建:
ON COMMIT
::
Table(
"some_table", metadata, ...,
prefixes=['GLOBAL TEMPORARY'], oracle_on_commit='PRESERVE ROWS')
1.0.0 新版功能.
COMPRESS
::
Table('mytable', metadata, Column('data', String(32)),
oracle_compress=True)
Table('mytable', metadata, Column('data', String(32)),
oracle_compress=6)
The ``oracle_compress`` parameter accepts either an integer compression
level, or ``True`` to use the default compression level.
1.0.0 新版功能.
您可以指定 oracle_bitmap
创建位图索引而不是B树索引的参数:
Index('my_index', my_table.c.data, oracle_bitmap=True)
位图索引不能是唯一的,也不能压缩。SQLAlchemy不会检查这样的限制,只有数据库会检查。
1.0.0 新版功能.
对于包含大量重复值的索引,Oracle具有更高效的存储模式。使用 oracle_compress
打开密钥压缩的参数:
Index('my_index', my_table.c.data, oracle_compress=True)
Index('my_index', my_table.c.data1, my_table.c.data2, unique=True,
oracle_compress=1)
这个 oracle_compress
参数接受指定要压缩的前缀列数的整数,或者 True
使用默认值(非唯一索引的所有列,唯一索引的最后一列除外)。
1.0.0 新版功能.
与所有的sqlAlchemy方言一样,已知对Oracle有效的所有大写类型都可以从顶级方言导入,无论它们是否源自 sqlalchemy.types
或者来自当地方言:
from sqlalchemy.dialects.oracle import \
BFILE, BLOB, CHAR, CLOB, DATE, \
DOUBLE_PRECISION, FLOAT, INTERVAL, LONG, NCLOB, NCHAR, \
NUMBER, NVARCHAR, NVARCHAR2, RAW, TIMESTAMP, VARCHAR, \
VARCHAR2
1.2.19 新版功能: 补充 NCHAR
到Oracle方言导出的数据类型列表。
特定于Oracle或具有Oracle特定构造参数的类型如下:
Object Name | Description |
---|---|
提供Oracle日期类型。 |
|
sqlalchemy.dialects.oracle.BFILE.
__init__(length=None)¶inherited from the sqlalchemy.types.LargeBinary.__init__
method of LargeBinary
构造一个大二进制类型。
length¶ -- 可选,用于ddl语句中的列的长度,用于接受长度的二进制类型,例如mysql blob类型。
提供Oracle日期类型。
此类型没有特殊的python行为,只是它的子类 DateTime
这是为了适应甲骨文 DATE
类型支持时间值。
0.9.4 新版功能.
sqlalchemy.dialects.oracle.DATE.
__init__(timezone=False)¶inherited from the sqlalchemy.types.DateTime.__init__
method of DateTime
构建新的 DateTime
.
sqlalchemy.dialects.oracle.DOUBLE_PRECISION.
__init__(precision=None, asdecimal=False, decimal_return_scale=None)¶inherited from the sqlalchemy.types.Float.__init__
method of Float
构造一个浮点。
precision¶ -- 用于DDL的数字精度 CREATE TABLE
.
asdecimal¶ -- 与…相同的标志 Numeric
,但默认为 False
. 请注意,将此标志设置为 True
导致浮点转换。
decimal_return_scale¶ -- 从浮点转换为python小数时使用的默认小数位数。由于小数点不准确,浮点值通常要长得多,而且大多数浮点数据库类型没有“小数位数”的概念,因此默认情况下,浮点类型在转换时查找前十位小数。指定此值将覆盖该长度。注意,如果没有另外指定,mysql float类型(包括“scale”)将使用“scale”作为decimal_return_scale的默认值。…版本已添加::0.9.0
类签名
class sqlalchemy.dialects.oracle.INTERVAL
(sqlalchemy.types.NativeForEmulated
, sqlalchemy.types._AbstractInterval
)
sqlalchemy.dialects.oracle.INTERVAL.
__init__(day_precision=None, second_precision=None)¶构造一个间隔。
请注意,目前只支持日到秒的时间间隔。这是由于在可用的dbapi中缺少对年到月间隔的支持。
sqlalchemy.dialects.oracle.NCLOB.
__init__(length=None, collation=None, convert_unicode=False, unicode_error=None, _warn_on_bytestring=False, _expect_unicode=False)¶inherited from the sqlalchemy.types.String.__init__
method of String
创建字符串保持类型。
length¶ -- 可选,用于DDL和CAST表达式的列的长度。如果没有,可以安全地省略 CREATE TABLE
将发布。某些数据库可能需要 length
在DDL中使用,并在 CREATE TABLE
如果 VARCHAR
不包括长度。该值是否解释为字节或字符是特定于数据库的。
collation¶ -- 可选,在DDL和CAST表达式中使用的列级排序规则。使用SQLite、MySQL和PostgreSQL支持的COLLATE关键字呈现。E、 g.:>>>从sqlalchemy import cast,select,String>>>打印(select(cast('some String',String(collation='utf8')))select cast(:param_1 AS VARCHAR COLLATE utf8)AS anon_
convert_unicode¶ -- 当设置为 True
, the String
类型将假定输入将作为python 2下的python unicode对象传递,结果将作为python unicode对象返回。在DBAPI在python 2下不支持pythonUnicode的罕见情况下,sqlachemy将在字符串上使用自己的编码器/解码器功能,参考 create_engine.encoding
参数参数传递给 create_engine()
作为编码。…已弃用::1.3 String.convert_unicode
参数已弃用,将在将来的版本中删除。所有现代DBAPI现在都直接支持PythonUnicode,而这个参数是不必要的。对于极为罕见的情况,python unicode将由sqlachemy在后端进行编码/解码, does 本机支持python unicode,字符串值 "force"
可以在此处传递,这将导致无条件使用SQLAlchemy的编码/解码服务。…注意::sqlacalchemy的unicode转换标志和特性只适用于python 2;在python 3中,所有字符串对象都是unicode对象。出于这个原因,以及事实上,几乎所有现代DBAPI现在都支持Unicode,即使在Python2下, String.convert_unicode
标志本身就是一个遗留功能。…注:在绝大多数情况下, Unicode
或 UnicodeText
数据类型应用于 Column
它期望存储非ascii数据。这些数据类型将确保在数据库端使用正确的类型,并在Python2下设置正确的Unicode行为。。另请参见: create_engine.convert_unicode
- Engine
宽参数
unicode_error¶ -- 可选,用于处理Unicode转换错误的方法。表现得像 errors
标准库的关键字参数 string.decode()
函数,要求 String.convert_unicode
设置为 "force"
…已弃用::1.3 String.unicode_errors
参数已弃用,将在将来的版本中删除。这个参数对于现代的python dbapis来说是不必要的,并且会显著降低性能。
sqlalchemy.dialects.oracle.NUMBER.
__init__(precision=None, scale=None, asdecimal=None)¶构造一个数字。
precision¶ -- 用于DDL的数字精度 CREATE TABLE
.
scale¶ -- DDL中使用的数字刻度 CREATE TABLE
.
asdecimal¶ -- 默认为真。返回值是否应作为python decimal对象或float发送。不同的dbapis根据数据类型发送一个或另一个-数字类型将确保返回值在dbapis中是一致的。
decimal_return_scale¶ -- 从浮点转换为python小数时使用的默认小数位数。由于小数点不准确,浮点值通常要长得多,而且大多数浮点数据库类型都没有“小数位数”的概念,因此默认情况下,浮点类型在转换时查找前十位小数。指定此值将覆盖该长度。包含显式“.scale”值的类型,如基 Numeric
以及mysql float类型,将使用“.scale”值作为decimal_return_scale的默认值,如果没有另外指定。…添加的版本:0.9.0
当使用 Numeric
类型,应注意确保asdecimal设置适用于正在使用的dbapi-当numeric应用decimal->float或float->decimal的转换时,此转换会对收到的所有结果列产生额外的性能开销。
本地返回十进制(例如psycopg2)的dbapis在设置为 True
,因为本机十进制转换减少了浮点问题的数量,并且数字类型本身不需要应用任何进一步的转换。但是,另一个DBAPI以本机方式返回浮动 will 产生额外的转换开销,并且仍然会受到浮点数据丢失的影响-在这种情况下 asdecimal=False
将至少移除额外的转换开销。
类签名
class sqlalchemy.dialects.oracle.LONG
(sqlalchemy.types.Text
)
sqlalchemy.dialects.oracle.LONG.
__init__(length=None, collation=None, convert_unicode=False, unicode_error=None, _warn_on_bytestring=False, _expect_unicode=False)¶inherited from the sqlalchemy.types.String.__init__
method of String
创建字符串保持类型。
length¶ -- 可选,用于DDL和CAST表达式的列的长度。如果没有,可以安全地省略 CREATE TABLE
将发布。某些数据库可能需要 length
在DDL中使用,并在 CREATE TABLE
如果 VARCHAR
不包括长度。该值是否解释为字节或字符是特定于数据库的。
collation¶ -- 可选,在DDL和CAST表达式中使用的列级排序规则。使用SQLite、MySQL和PostgreSQL支持的COLLATE关键字呈现。E、 g.:>>>从sqlalchemy import cast,select,String>>>打印(select(cast('some String',String(collation='utf8')))select cast(:param_1 AS VARCHAR COLLATE utf8)AS anon_
convert_unicode¶ -- 当设置为 True
, the String
类型将假定输入将作为python 2下的python unicode对象传递,结果将作为python unicode对象返回。在DBAPI在python 2下不支持pythonUnicode的罕见情况下,sqlachemy将在字符串上使用自己的编码器/解码器功能,参考 create_engine.encoding
参数参数传递给 create_engine()
作为编码。…已弃用::1.3 String.convert_unicode
参数已弃用,将在将来的版本中删除。所有现代DBAPI现在都直接支持PythonUnicode,而这个参数是不必要的。对于极为罕见的情况,python unicode将由sqlachemy在后端进行编码/解码, does 本机支持python unicode,字符串值 "force"
可以在此处传递,这将导致无条件使用SQLAlchemy的编码/解码服务。…注意::sqlacalchemy的unicode转换标志和特性只适用于python 2;在python 3中,所有字符串对象都是unicode对象。出于这个原因,以及事实上,几乎所有现代DBAPI现在都支持Unicode,即使在Python2下, String.convert_unicode
标志本身就是一个遗留功能。…注:在绝大多数情况下, Unicode
或 UnicodeText
数据类型应用于 Column
它期望存储非ascii数据。这些数据类型将确保在数据库端使用正确的类型,并在Python2下设置正确的Unicode行为。。另请参见: create_engine.convert_unicode
- Engine
宽参数
unicode_error¶ -- 可选,用于处理Unicode转换错误的方法。表现得像 errors
标准库的关键字参数 string.decode()
函数,要求 String.convert_unicode
设置为 "force"
…已弃用::1.3 String.unicode_errors
参数已弃用,将在将来的版本中删除。这个参数对于现代的python dbapis来说是不必要的,并且会显著降低性能。
类签名
class sqlalchemy.dialects.oracle.RAW
(sqlalchemy.types._Binary
)
sqlalchemy.dialects.oracle.RAW.
__init__(length=None)¶inherited from the sqlalchemy.types._Binary.__init__
method of sqlalchemy.types._Binary
Support for the Oracle database via the cx-Oracle driver.
Documentation and download information (if applicable) for cx-Oracle is available at: https://oracle.github.io/python-cx_Oracle/
Connect String:
oracle+cx_oracle://user:pass@hostname:port[/dbname][?service_name=<service>[&key=value&key=value...]]
CX_ORACLE提供了几种指示目标数据库的方法。该方言从一系列不同的URL形式翻译而来。
给定目标Oracle数据库的主机名、端口和服务名,例如来自Oracle的 Easy Connect syntax ,然后在SQLAlChemy中使用 service_name
查询字符串参数::
engine = create_engine("oracle+cx_oracle://scott:tiger@hostname:port/?service_name=myservice&encoding=UTF-8&nencoding=UTF-8")
这个 full Easy Connect syntax 不受支持。相反,请使用 tnsnames.ora
文件并使用DSN连接。
或者,如果没有端口、数据库名称或 service_name
则方言将使用Oracle DSN“连接字符串”。这将URL的“hostname”部分作为数据源名称。例如,如果 tnsnames.ora
文件包含一个 Net Service Name 的 myalias
详情如下:
myalias =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = mymachine.example.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orclpdb1)
)
)
CX_ORACLE方言在以下情况下连接到此数据库服务 myalias
是URL的主机名部分,不指定端口、数据库名称或 service_name
::
engine = create_engine("oracle+cx_oracle://scott:tiger@myalias/?encoding=UTF-8&nencoding=UTF-8")
Oracle Cloud的用户应使用此语法,并按照CX_ORACLE文档中所示配置云Wallet Connecting to Autononmous Databases 。
要使用Oracle过时的SID连接语法,可以在URL的“数据库名”部分传递SID,如下所示:
engine = create_engine("oracle+cx_oracle://scott:tiger@hostname:1521/dbname?encoding=UTF-8&nencoding=UTF-8")
上面,传递到CX_ORACLE的DSN是由创建的 cx_Oracle.makedsn()
详情如下:
>>> import cx_Oracle
>>> cx_Oracle.makedsn("hostname", 1521, sid="dbname")
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=1521))(CONNECT_DATA=(SID=dbname)))'
附加的连接参数通常可以通过URL查询字符串传递;特定的符号如 cx_Oracle.SYSDBA
截取并转换为正确的符号:
e = create_engine(
"oracle+cx_oracle://user:pass@dsn?encoding=UTF-8&nencoding=UTF-8&mode=SYSDBA&events=true")
在 1.3 版更改: cx-oracle方言现在接受URL字符串本身中的所有参数名,并将其传递给cx-oracle dbapi。如前所述,但没有正确记录, create_engine.connect_args
参数还接受所有cx_oracle dbapi connect参数。
将参数直接传递给 .connect()
在不使用查询字符串的情况下,使用 create_engine.connect_args
字典。可以传递任何CX_ORACLE参数值和/或常量,例如:
import cx_Oracle
e = create_engine(
"oracle+cx_oracle://user:pass@dsn",
connect_args={
"encoding": "UTF-8",
"nencoding": "UTF-8",
"mode": cx_Oracle.SYSDBA,
"events": True
}
)
请注意,的默认值为 encoding
和 nencoding
在CX_ORACLE 8.0中更改为“UTF-8”,因此在使用该版本或更高版本时可以省略这些参数。
还有一些选项被sqlacalchemy cx_Oracle方言本身所使用。这些选项总是直接传递给 create_engine()
,例如:
e = create_engine(
"oracle+cx_oracle://user:pass@dsn", coerce_to_unicode=False)
cx_Oracle方言接受的参数如下:
CX_ORACLE库提供了自己的连接池实现,可以用来代替SQLAlChemy的池功能。这可以通过使用 create_engine.creator
参数提供返回新连接的函数,以及设置 create_engine.pool_class
至 NullPool
要禁用SQLAlChemy的池化,请执行以下操作:
import cx_Oracle
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
pool = cx_Oracle.SessionPool(
user="scott", password="tiger", dsn="orclpdb",
min=2, max=5, increment=1, threaded=True,
encoding="UTF-8", nencoding="UTF-8"
)
engine = create_engine("oracle://", creator=pool.acquire, poolclass=NullPool)
然后,在CX_ORACLE的池处理连接池的情况下,可以正常使用上述引擎::
with engine.connect() as conn:
print(conn.scalar("select 1 FROM dual"))
除了为多用户应用程序提供可扩展的解决方案外,CX_ORACLE会话池还支持一些Oracle功能,如DRCP和 Application Continuity 。
在使用Oracle的 DRCP 最佳实践是在从SessionPool获取连接时传递连接类和“纯度”。请参阅 cx_Oracle DRCP documentation 。
这可以通过包装来实现 pool.acquire()
::
import cx_Oracle
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
pool = cx_Oracle.SessionPool(
user="scott", password="tiger", dsn="orclpdb",
min=2, max=5, increment=1, threaded=True,
encoding="UTF-8", nencoding="UTF-8"
)
def creator():
return pool.acquire(cclass="MYCLASS", purity=cx_Oracle.ATTR_PURITY_SELF)
engine = create_engine("oracle://", creator=creator, poolclass=NullPool)
然后,在CX_ORACLE处理会话池并且Oracle数据库另外使用DRCP::的情况下,可以正常使用上述引擎
with engine.connect() as conn:
print(conn.scalar("select 1 FROM dual"))
与python3下的所有dbapi一样,所有字符串本质上都是Unicode字符串。在python2下,cx峈Oracle还直接支持Python Unicode对象。但是,在所有情况下,驱动程序都需要显式的编码配置。
为几乎所有与Oracle相关的软件建立客户端编码的长期接受的标准是通过 NLS_LANG 环境变量。与大多数其他Oracle驱动程序一样,cxU Oracle将使用此环境变量作为其编码配置的源。此变量的格式是特殊的;典型的值是 AMERICAN_AMERICA.AL32UTF8
.
除了支持Oracle U pass的编程驱动程序之外,还有一种可选的方法 encoding
和 nencoding
直接将参数 .connect()
功能。这些可以在URL中显示,如下所示:
engine = create_engine("oracle+cx_oracle://scott:tiger@orclpdb/?encoding=UTF-8&nencoding=UTF-8")
关于 encoding
和 nencoding
参数,请参考 Characters Sets and National Language Support (NLS) .
参见
Characters Sets and National Language Support (NLS) -在cx_Oracle文档中。
核心表达式语言通过使用 Unicode
和 UnicodeText
数据类型。默认情况下,这些类型对应于VARCHAR2和CLOB Oracle数据类型。当将这些数据类型与Unicode数据一起使用时,Oracle数据库应该配置有一个支持Unicode的字符集,并且 NLS_LANG
环境变量被适当地设置,以便varchar2和clob数据类型能够容纳数据。
如果Oracle数据库未配置Unicode字符集,则两个选项将使用 NCHAR
和 NCLOB
显式的数据类型,或传递标志 use_nchar_for_unicode=True
到 create_engine()
,这将导致sqlAlchemy方言将nchar/nclob用于 Unicode
/ UnicodeText
数据类型,而不是varchar/clob。
在 1.3 版更改: 这个 Unicode
和 UnicodeText
数据类型现在对应于 VARCHAR2
和 CLOB
Oracle数据类型,除非 use_nchar_for_unicode=True
当 create_engine()
被称为。
当获取包含字符串的结果集时,在python 3下,cx_Oracle DBAPI将所有字符串作为python unicode对象返回,因为python 3只有unicode字符串类型。对于从varchar2、char、clob、nchar、nclob等数据类型中提取的数据,会发生这种情况。为了在python 2下提供交叉兼容性,sqlachemy cx_oracle方言也会将unicode转换添加到python 2下的字符串数据中。历史上,这使用了由cx_oracle提供但被发现没有性能的转换器;sqlAlchemy自己的转换器用于python 2下的字符串到unicode转换。要禁用varchar2、char和clob的python 2 unicode转换,标志 coerce_to_unicode=False
可以传递给 create_engine()
.
在 1.3 版更改: 在python 2下,默认情况下,Unicode转换应用于所有字符串值。这个 coerce_to_unicode
现在默认为true,可以设置为false以禁用以varchar2/char/clob数据形式传递的字符串的Unicode强制。
对于Oracle数据库中的数据以损坏的编码存在的异常情况,方言接受一个参数 encoding_errors
它将传递给Unicode解码函数,以影响如何处理解码错误。这个值最终由Python使用 decode 函数,并通过cx_Oracle的 encodingErrors
参数消耗者 Cursor.var()
,以及SQLAlchemy自己的解码功能,因为cx峈Oracle方言在不同的情况下使用了这两种语言。
1.3.11 新版功能.
cx-oracle dbapi对dbapi的使用有着深刻而基本的依赖性 setinputsizes()
打电话。此调用的目的是为作为参数传递的python值建立绑定到SQL语句的数据类型。实际上没有其他DBAPI为 setinputsizes()
调用时,cx-oracle dbapi在与Oracle客户机接口的交互中非常依赖于它,在某些情况下,sqlAlchemy不可能确切地知道应该如何绑定数据,因为某些设置可能会导致性能特征极为不同,同时改变类型强制行为。
CX_ORACLE方言的用户为 强烈鼓励 在https://cx-oracle.readthedocs.io/en/latest/api_manual/module.html#database-types.上阅读CX_ORACLE的内置数据类型符号列表请注意,在某些情况下,使用这些类型与不使用这些类型相比,性能可能会显著降低,特别是在指定 cx_Oracle.CLOB
。
在炼金术方面, DialectEvents.do_setinputsizes()
事件既可用于setinputsizes步骤的运行时可见性(例如日志记录),也可用于完全控制 setinputsizes()
按语句使用。
1.2.9 新版功能: 补充 DialectEvents.setinputsizes()
下面的示例说明如何在将中间值转换为原始值之前,从SQLAlchemy的角度记录它们。 setinputsizes()
参数字典。字典的关键是 BindParameter
具有 .key
和A .type
属性:
from sqlalchemy import create_engine, event
engine = create_engine("oracle+cx_oracle://scott:tiger@host/xe")
@event.listens_for(engine, "do_setinputsizes")
def _log_setinputsizes(inputsizes, cursor, statement, parameters, context):
for bindparam, dbapitype in inputsizes.items():
log.info(
"Bound parameter name: %s SQLAlchemy type: %r "
"DBAPI object: %s",
bindparam.key, bindparam.type, dbapitype)
这个 CLOB
cx_oracle中的数据类型会产生很大的性能开销,但是默认情况下会为 Text
在sqlacalchemy 1.2系列中键入。此设置可以修改如下:
from sqlalchemy import create_engine, event
from cx_Oracle import CLOB
engine = create_engine("oracle+cx_oracle://scott:tiger@host/xe")
@event.listens_for(engine, "do_setinputsizes")
def _remove_clob(inputsizes, cursor, statement, parameters, context):
for bindparam, dbapitype in list(inputsizes.items()):
if dbapitype is CLOB:
del inputsizes[bindparam]
cx_Oracle方言实现使用out参数返回。方言支持完全返回,但建议使用cx_oracle 6以获得完全支持。
cx_oracle使用cx_oracle.lob对象返回Oracle LOB。sqlAlchemy将这些转换为字符串,以便二进制类型的接口与其他后端的接口一致,后者发生在cx_Oracle OutputTypeHandler中。
cx_Oracle在版本6之前将要求在读取新批行之前读取lob对象,这由 cursor.arraysize
. 从6系列开始,此限制已解除。不过,由于sqlacalchemy预先读取这些LOB,所以无论如何都可以避免这个问题。
要禁用方言的自动“read()”功能,标志 auto_convert_lobs=False
可传递给 create_engine()
. 在cx-oracle 5系列中,关闭此标志意味着如果在提取过时的lob对象时不读取它,则有可能读取该对象。使用cx_Oracle 6,可以解决此问题。
在 1.2 版更改: LOB处理系统在内部被大大简化以使用outputtypehanders,不再使用备用的“缓冲”结果集对象。
两阶段交易是 不支持 在cx_Oracle下,由于驱动程序支持不佳。从cx_oracle 6.0b1开始,两阶段事务的接口已更改为更直接地传递到底层OCI层,自动化程度更低。支持此系统的附加逻辑未在SQLAlchemy中实现。
sqlAlchemy的numeric类型可以像python那样处理接收和返回值 Decimal
对象或浮动对象。当A Numeric
对象或子类,如 Float
, DOUBLE_PRECISION
等正在使用中, Numeric.asdecimal
标志确定是否应将值强制为 Decimal
返回时,或作为浮动对象返回。为了使甲骨文下的事情更加复杂,甲骨文的 NUMBER
如果“scale”为零,类型还可以表示整数值,因此Oracle特定 NUMBER
类型也考虑到这一点。
cx-oracle方言广泛使用连接级和光标级的“outputtypehander”可调用文件,以便按要求强制使用数值。这些可调用物是特定于 Numeric
在使用中,以及如果不存在任何SQLAlchemy类型对象。在观察到的情况下,Oracle可能会发送有关返回的数字类型的不完整或不明确的信息,例如,将数字类型隐藏在多个级别的子查询下的查询。类型处理程序在所有情况下都尽其所能做出正确的决策,对于驱动程序能够做出最佳决策的所有情况,都遵从底层的cx_Oracle DBAPI。
当没有输入对象时,如执行普通的SQL字符串时,会出现一个默认的“outputTypeHandler”,它通常会返回指定精度和比例为python的数值。 Decimal
物体。若要出于性能原因禁用强制小数,请传递标志 coerce_to_decimal=False
到 create_engine()
::
engine = create_engine("oracle+cx_oracle://dsn", coerce_to_decimal=False)
这个 coerce_to_decimal
标志仅影响纯字符串SQL语句的结果,否则这些语句与 Numeric
SQLAlChemy类型(或此类类型的子类)。
flambé! the dragon and The Alchemist image designs created and generously donated by Rotem Yaari.
Created using Sphinx 4.2.0.