SqlAlchemy 2.0 中文文档(五十一)(3)https://developer.aliyun.com/article/1563197
Oracle 数据类型
与所有 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 特定构造参数的类型:
对象名称 | 描述 |
BFILE | |
BINARY_DOUBLE | |
BINARY_FLOAT | |
DATE | 提供 Oracle DATE 类型。 |
FLOAT | Oracle FLOAT 类型。 |
INTERVAL | |
LONG | |
NCLOB | |
NUMBER | |
NVARCHAR2 | NVARCHAR 的别名 |
RAW | |
ROWID | Oracle ROWID 类型。 |
TIMESTAMP | TIMESTAMP 的 Oracle 实现,支持额外的 Oracle 特定模式。 |
class sqlalchemy.dialects.oracle.BFILE
成员
init()
类签名
class sqlalchemy.dialects.oracle.BFILE
(sqlalchemy.types.LargeBinary
)
method __init__(length: int | None = None)
继承自 LargeBinary
的 sqlalchemy.types.LargeBinary.__init__
方法
构造一个 LargeBinary 类型。
参数:
length – 可选,用于 DDL 语句中的列长度,适用于接受长度的二进制类型,如 MySQL 的 BLOB 类型。
class sqlalchemy.dialects.oracle.BINARY_DOUBLE
成员
init()
类签名
class sqlalchemy.dialects.oracle.BINARY_DOUBLE
(sqlalchemy.types.Double
)
method __init__(precision: int | None = None, asdecimal: bool = False, decimal_return_scale: int | None = None)
继承自 Float
的 sqlalchemy.types.Float.__init__
方法
构造一个 Float。
参数:
precision
–
用于 DDLCREATE TABLE
中的数值精度。后端应该尽量确保此精度指示了通用Float
数据类型的数字位数。
注意
对于 Oracle 后端,在渲染 DDL 时不接受Float.precision
参数,因为 Oracle 不支持将浮点精度指定为小数位数。而是使用 Oracle 特定的FLOAT
数据类型,并指定FLOAT.binary_precision
参数。这是 SQLAlchemy 的 2.0 版本中的新功能。
要创建一个数据库通用的Float
,并分别为 Oracle 指定二进制精度,请使用TypeEngine.with_variant()
如下:
from sqlalchemy import Column from sqlalchemy import Float from sqlalchemy.dialects import oracle Column( "float_data", Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle") ) • 8
asdecimal
– 与Numeric
相同的标志,但默认值为False
。请注意,将此标志设置为True
会导致浮点转换。decimal_return_scale
– 将浮点数转换为 Python 十进制时使用的默认标度。由于十进制不准确,浮点值通常会更长,并且大多数浮点数据库类型都没有“标度”的概念,因此默认情况下,浮点类型在转换时会查找前十位小数点。指定此值将覆盖该长度。请注意,MySQL 浮点类型(包括“标度”)将使用“标度”作为 decimal_return_scale 的默认值,如果未另行指定。
class sqlalchemy.dialects.oracle.BINARY_FLOAT
成员
init()
类签名
类sqlalchemy.dialects.oracle.BINARY_FLOAT
(sqlalchemy.types.Float
)
method __init__(precision: int | None = None, asdecimal: bool = False, decimal_return_scale: int | None = None)
从 Float
的 sqlalchemy.types.Float.__init__
方法继承而来
构造一个 Float。
参数:
precision
–
用于 DDLCREATE TABLE
中的数值精度。后端应该尽量确保此精度指示了通用Float
数据类型的数字位数。
注意
对于 Oracle 后端,在渲染 DDL 时不接受Float.precision
参数,因为 Oracle 不支持指定浮点精度为小数位数。 *相反,使用特定于 Oracle 的FLOAT
数据类型,并指定FLOAT.binary_precision
参数。 这是 SQLAlchemy 的 2.0 新功能。
要创建一个数据库通用的Float
,为 Oracle 分别指定二进制精度,请使用TypeEngine.with_variant()
如下所示:
from sqlalchemy import Column from sqlalchemy import Float from sqlalchemy.dialects import oracle Column( "float_data", Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle") )
asdecimal
– 与Numeric
相同的标志,但默认为False
。请注意,将此标志设置为True
将导致浮点数转换。decimal_return_scale
– 在从浮点数转换为 Python 十进制数时要使用的默认比例。由于十进制不精确,浮点数值通常会更长,并且大多数浮点数数据库类型没有“比例”的概念,因此默认情况下,浮点类型在转换时会寻找前十位小数位数。指定此值将覆盖该长度。请注意,如果没有另行指定,具有“比例”的 MySQL 浮点类型将使用“比例”作为decimal_return_scale
的默认值。
class sqlalchemy.dialects.oracle.DATE
提供 Oracle DATE 类型。
此类型在 Python 中没有特殊的行为,除了它是 DateTime
的子类;这是为了适应 Oracle DATE
类型支持时间值的事实。
成员
init()
类签名
class sqlalchemy.dialects.oracle.DATE
(sqlalchemy.dialects.oracle.types._OracleDateLiteralRender
, sqlalchemy.types.DateTime
)
method __init__(timezone: bool = False)
继承自 DateTime
方法的 sqlalchemy.types.DateTime.__init__
方法
构造一个新的 DateTime
。
参数:
时区 – 布尔值。指示日期时间类型应在仅在基本日期/时间保持类型上可用时启用时区支持。建议在使用此标志时直接使用TIMESTAMP
数据类型,因为某些数据库包括与时区支持 TIMESTAMP 数据类型不同的通用日期/时间保持类型,如 Oracle。
class sqlalchemy.dialects.oracle.FLOAT
Oracle FLOAT。
这与FLOAT
相同,不同之处在于接受一个 Oracle 特定的FLOAT.binary_precision
参数,并且不接受Float.precision
参数。
Oracle FLOAT 类型以“二进制精度”表示精度,默认为 126。对于 REAL 类型,该值为 63。该参数不清晰地映射到特定数量的小数位,但大致相当于所需小数位数除以 0.3103。
新版本 2.0 中新增。
成员
init()
类签名
类sqlalchemy.dialects.oracle.FLOAT
(sqlalchemy.types.FLOAT
)
method __init__(binary_precision=None, asdecimal=False, decimal_return_scale=None)
构造一个浮点数
参数:
binary_precision
– 要在 DDL 中呈现的 Oracle 二进制精度值。这可以使用公式“十进制精度 = 0.30103 * 二进制精度”来近似为十进制字符的数量。Oracle 用于 FLOAT / DOUBLE PRECISION 的默认值为 126。asdecimal
– 参见Float.asdecimal
decimal_return_scale
– 参见Float.decimal_return_scale
class sqlalchemy.dialects.oracle.INTERVAL
成员
init()
类签名
类sqlalchemy.dialects.oracle.INTERVAL
(sqlalchemy.types.NativeForEmulated
, sqlalchemy.types._AbstractInterval
)
method __init__(day_precision=None, second_precision=None)
构造一个间隔。
请注意,目前仅支持“DAY TO SECOND”间隔。这是由于可用的 DBAPI 不支持“YEAR TO MONTH”间隔。
参数:
day_precision
– 天精度值。这是用于存储天字段的数字位数。默认为“2”second_precision
– 秒精度值。这是用于存储小数秒字段的数字位数。默认为“6”。
class sqlalchemy.dialects.oracle.NCLOB
成员
init()
类签名
class sqlalchemy.dialects.oracle.NCLOB
(sqlalchemy.types.Text
)
method __init__(length: int | None = None, collation: str | None = None)
继承自 String
的 sqlalchemy.types.String.__init__
方法
创建一个持有字符串的类型。
参数:
length
– 可选,用于 DDL 和 CAST 表达式中的列长度。如果不会发出CREATE TABLE
,则可以安全地省略。某些数据库可能需要在 DDL 中使用length
,如果包含没有长度的VARCHAR
,则在发出CREATE TABLE
DDL 时会引发异常。值是以字节还是字符解释是特定于数据库的。collation
–
可选,用于 DDL 和 CAST 表达式中的列级排序。使用 SQLite、MySQL 和 PostgreSQL 支持的 COLLATE 关键字进行呈现。例如:
>>> from sqlalchemy import cast, select, String >>> print(select(cast('some string', String(collation='utf8')))) SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1
- 注意
在大多数情况下,Column
预计存储非 ASCII 数据的列应使用Unicode
或UnicodeText
数据类型。这些数据类型将确保在数据库上使用正确的类型。
attribute sqlalchemy.dialects.oracle.NVARCHAR2
别名为 NVARCHAR
class sqlalchemy.dialects.oracle.NUMBER
类签名
class sqlalchemy.dialects.oracle.NUMBER
(sqlalchemy.types.Numeric
, sqlalchemy.types.Integer
)
class sqlalchemy.dialects.oracle.LONG
成员
init()
类签名
class sqlalchemy.dialects.oracle.LONG
(sqlalchemy.types.Text
)
method __init__(length: int | None = None, collation: str | None = None)
继承自 String
的 sqlalchemy.types.String.__init__
方法
创建一个持有字符串的类型。
参数:
length
– 可选,用于 DDL 和 CAST 表达式中的列长度。如果不会发出CREATE TABLE
,则可以安全地省略。某些数据库可能需要在 DDL 中���用length
,如果包含没有长度的VARCHAR
,则在发出CREATE TABLE
DDL 时会引发异常。值是以字节还是字符解释是特定于数据库的。collation
–
可选,用于 DDL 和 CAST 表达式中的列级排序。使用 SQLite、MySQL 和 PostgreSQL 支持的 COLLATE 关键字进行呈现。例如:
>>> from sqlalchemy import cast, select, String >>> print(select(cast('some string', String(collation='utf8')))) SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1
- 注意
在大多数情况下,应该使用Unicode
或UnicodeText
数据类型来存储非 ASCII 数据的Column
。这些数据类型将确保在数据库上使用正确的类型。
class sqlalchemy.dialects.oracle.RAW
类签名
类 sqlalchemy.dialects.oracle.RAW
(sqlalchemy.types._Binary
)
class sqlalchemy.dialects.oracle.ROWID
Oracle ROWID 类型。
当在 cast() 或类似情况下使用时,生成 ROWID。
类签名
类 sqlalchemy.dialects.oracle.ROWID
(sqlalchemy.types.TypeEngine
)
class sqlalchemy.dialects.oracle.TIMESTAMP
Oracle 实现的 TIMESTAMP
,支持附加的 Oracle 特定模式
2.0 版本中的新增功能。
成员
init()
类签名
类 sqlalchemy.dialects.oracle.TIMESTAMP
(sqlalchemy.types.TIMESTAMP
)
method __init__(timezone: bool = False, local_timezone: bool = False)
构造一个新的 TIMESTAMP
。
参数:
timezone
– 布尔值。指示 TIMESTAMP 类型应该使用 Oracle 的TIMESTAMP WITH TIME ZONE
数据类型。local_timezone
– 布尔值。指示 TIMESTAMP 类型应该使用 Oracle 的TIMESTAMP WITH LOCAL TIME ZONE
数据类型。
cx_Oracle
通过 cx-Oracle 驱动程序支持 Oracle 数据库。
DBAPI
cx-Oracle 的文档和下载信息(如果适用)可在此处找到:oracle.github.io/python-cx_Oracle/
连接
连接字符串:
oracle+cx_oracle://user:pass@hostname:port[/dbname][?service_name=<service>[&key=value&key=value...]]
DSN vs. 主机名连接
cx_Oracle 提供了几种指示目标数据库的方法。方言从一系列不同的 URL 形式转换而来。
使用 Easy Connect 语法的主机名连接
给定目标 Oracle 数据库的主机名、端口和服务名称,例如来自 Oracle 的 Easy Connect 语法,然后使用 SQLAlchemy 中的 service_name
查询字符串参数进行连接:
engine = create_engine("oracle+cx_oracle://scott:tiger@hostname:port/?service_name=myservice&encoding=UTF-8&nencoding=UTF-8")
完整的 Easy Connect 语法不受支持。请使用 tnsnames.ora
文件,并使用 DSN 进行连接。
与 tnsnames.ora 或 Oracle Cloud 的连接
或者,如果未提供端口、数据库名称或 service_name
,则方言将使用 Oracle DSN “连接字符串”。这将“主机名”部分的 URL 作为数据源名称。例如,如果 tnsnames.ora
文件包含以下内容的 Net Service Name:
myalias = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = mymachine.example.com)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orclpdb1) ) )
当 myalias
是 URL 的主机名部分时,cx_Oracle 方言将连接到此数据库服务,而不指定端口、数据库名称或 service_name
:
engine = create_engine("oracle+cx_oracle://scott:tiger@myalias/?encoding=UTF-8&nencoding=UTF-8")
Oracle Cloud 的用户应该使用此语法,并按照 cx_Oracle 文档中所示配置云钱包 连接到自主数据库。
SID 连接
要使用 Oracle 的过时 SID 连接语法,SID 可以在 URL 的“数据库名称”部分中传递,如下所示:
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)))'
传递 cx_Oracle 连接参数
通常可以通过 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()
而不使用查询字符串,可以使用 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 } )
请注意,在 cx_Oracle 8.0 中,encoding
和 nencoding
的默认值已更改为“UTF-8”,因此在使用该版本或更高版本时,可以省略这些参数。
在驱动程序之外由 SQLAlchemy cx_Oracle 方言消耗的选项
还有一些选项是由 SQLAlchemy cx_oracle 方言本身消耗的。这些选项总是直接传递给 create_engine()
,例如:
e = create_engine( "oracle+cx_oracle://user:pass@dsn", coerce_to_decimal=False)
cx_oracle 方言接受的参数如下:
arraysize
- 在游标上设置 cx_oracle.arraysize 值;默认为None
,表示应使用驱动程序的默认值(通常该值为 100)。此设置控制在获取行时缓冲多少行,并且在修改时可能对性能产生重大影响。该设置用于cx_Oracle
以及oracledb
。
从版本 2.0.26 起更改:- 将默认值从 50 更改为 None,以使用驱动程序本身的默认值。auto_convert_lobs
- 默认为 True;详见 LOB 数据类型。coerce_to_decimal
- 详见精确数值。encoding_errors
- 详见编码错误。
使用 cx_Oracle SessionPool
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+cx_oracle://", creator=pool.acquire, poolclass=NullPool)
上述引擎可以正常使用,其中 cx_Oracle 的池处理连接池:
with engine.connect() as conn: print(conn.scalar("select 1 FROM dual"))
除了为多用户应用程序提供可扩展的解决方案外,cx_Oracle 会话池还支持一些 Oracle 功能,如 DRCP 和应用连续性。
使用 Oracle 数据库 Resident Connection Pooling(DRCP)
在使用 Oracle 的DRCP时,最佳实践是在从 SessionPool 获取连接时传递连接类和“纯度”。请参阅cx_Oracle DRCP 文档。
这可以通过包装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+cx_oracle://", creator=creator, poolclass=NullPool)
上述引擎可以正常使用,其中 cx_Oracle 处理会话池,Oracle 数据库另外使用 DRCP:
with engine.connect() as conn: print(conn.scalar("select 1 FROM dual"))
SqlAlchemy 2.0 中文文档(五十一)(5)https://developer.aliyun.com/article/1563200