引擎配置

Engine 是任何 SQLAlchemy 应用程序的起点。它是实际数据库及其 DBAPI 的“主基地”,通过连接池和 Dialect 传递给 SQLAlchemy 应用程序,它描述了如何与特定类型的数据库/DBAPI 组合进行通信。

一般结构可以说明如下

../_images/sqla_engine_arch.png

在上面,Engine 同时引用 DialectPool,它们共同解释 DBAPI 的模块函数以及数据库的行为。

创建引擎只需发出一个调用,create_engine()

from sqlalchemy import create_engine

engine = create_engine("postgresql+psycopg2://scott:tiger@localhost:5432/mydatabase")

以上引擎创建一个针对 PostgreSQL 定制的 Dialect 对象,以及一个 Pool 对象,该对象将在首次收到连接请求时在 localhost:5432 建立 DBAPI 连接。请注意,Engine 及其底层的 Pool 不会 在调用 Engine.connect()Engine.begin() 方法之前建立第一个实际的 DBAPI 连接。这两个方法也可能被其他 SQLAlchemy Engine 依赖对象调用,例如 ORM Session 对象,当它们第一次需要数据库连接时。这样,EnginePool 可以说具有延迟初始化行为。

创建后,Engine 可以直接用于与数据库交互,也可以传递给 Session 对象以使用 ORM。本节介绍配置 Engine 的详细信息。下一节,使用引擎和连接,将详细介绍 Engine 以及类似对象的用法 API,通常用于非 ORM 应用程序。

支持的数据库

SQLAlchemy 包含许多 Dialect 实现,适用于各种后端。最常用数据库的方言包含在 SQLAlchemy 中;其他一些则需要额外安装独立的方言。

有关各种可用后端的详细信息,请参见 方言 部分。

数据库 URL

create_engine() 函数根据 URL 生成一个 Engine 对象。URL 的格式通常遵循 RFC-1738,但有一些例外,包括“方案”部分接受下划线,而不是短横线或句点。URL 通常包含用户名、密码、主机名、数据库名称字段,以及用于额外配置的可选关键字参数。在某些情况下,接受文件路径,在其他情况下,“数据源名称”替换“主机”和“数据库”部分。数据库 URL 的典型形式为

dialect+driver://username:password@host:port/database

方言名称包括 SQLAlchemy 方言的标识名称,例如 sqlitemysqlpostgresqloraclemssql。drivername 是要用于使用全部小写字母连接到数据库的 DBAPI 的名称。如果未指定,则会导入可用的“默认”DBAPI - 此默认值通常是该后端最广为人知的驱动程序。

转义特殊字符,例如密码中的 @ 符号

构造要传递给 create_engine() 的完整 URL 字符串时,必须对特殊字符(例如可能用在用户和密码中的字符)进行 URL 编码,才能正确解析这包括 @ 符号

以下是一个包含密码 "kx@jj5/g" 的 URL 示例,其中“at”符号和斜杠字符分别表示为 %40%2F

postgresql+pg8000://dbuser:kx%40jj5%2Fg@pghost10/appdb

上面密码的编码可以使用 urllib.parse 生成。

>>> import urllib.parse
>>> urllib.parse.quote_plus("kx@jj5/g")
'kx%40jj5%2Fg'

然后可以将 URL 作为字符串传递给 create_engine()

from sqlalchemy import create_engine

engine = create_engine("postgresql+pg8000://dbuser:kx%40jj5%2Fg@pghost10/appdb")

作为对转义特殊字符以创建完整 URL 字符串的替代方案,传递给 create_engine() 的对象可以是 URL 对象的实例,它绕过解析阶段,可以直接处理未转义的字符串。请参阅下一节以获取示例。

在版本 1.4 中更改: 已修复对主机名和数据库名称中的 @ 符号的支持。作为此修复的副作用,密码中的 @ 符号必须转义。

以编程方式创建 URL

传递给 create_engine() 的值可以是 URL 的实例,而不是普通字符串,这绕过了对字符串解析的需求,因此不需要提供转义的 URL 字符串。

使用 URL.create() 构造方法创建 URL 对象,分别传递所有字段。特殊字符(例如密码中的字符)可以不加修改地传递。

from sqlalchemy import URL

url_object = URL.create(
    "postgresql+pg8000",
    username="dbuser",
    password="kx@jj5/g",  # plain (unescaped) text
    host="pghost10",
    database="appdb",
)

然后可以将构造的 URL 对象直接传递给 create_engine() 来代替字符串参数。

from sqlalchemy import create_engine

engine = create_engine(url_object)

另请参阅

URL

URL.create()

特定于后端的 URL

下面是常见连接方式的示例。有关所有包含的方言的详细信息的完整索引以及指向第三方方言的链接,请参阅 方言

PostgreSQL

PostgreSQL 方言使用 psycopg2 作为默认 DBAPI。其他 PostgreSQL DBAPI 包括 pg8000 和 asyncpg。

# default
engine = create_engine("postgresql://scott:tiger@localhost/mydatabase")

# psycopg2
engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/mydatabase")

# pg8000
engine = create_engine("postgresql+pg8000://scott:tiger@localhost/mydatabase")

有关连接到 PostgreSQL 的更多说明,请参阅 PostgreSQL

MySQL

MySQL 方言使用 mysqlclient 作为默认 DBAPI。还有其他可用的 MySQL DBAPI,包括 PyMySQL。

# default
engine = create_engine("mysql://scott:tiger@localhost/foo")

# mysqlclient (a maintained fork of MySQL-Python)
engine = create_engine("mysql+mysqldb://scott:tiger@localhost/foo")

# PyMySQL
engine = create_engine("mysql+pymysql://scott:tiger@localhost/foo")

有关连接到 MySQL 的更多说明,请参阅 MySQL 和 MariaDB

Oracle

Oracle 方言使用 cx_oracle 作为默认 DBAPI。

engine = create_engine("oracle://scott:[email protected]:1521/sidname")

engine = create_engine("oracle+cx_oracle://scott:tiger@tnsname")

有关连接到 Oracle 的更多说明,请参阅 Oracle

Microsoft SQL Server

SQL Server 方言使用 pyodbc 作为默认 DBAPI。pymssql 也可用。

# pyodbc
engine = create_engine("mssql+pyodbc://scott:tiger@mydsn")

# pymssql
engine = create_engine("mssql+pymssql://scott:tiger@hostname:port/dbname")

有关连接到 SQL Server 的更多说明,请参阅 Microsoft SQL Server

SQLite

SQLite 连接到基于文件的数据库,默认情况下使用 Python 内置模块 sqlite3

由于 SQLite 连接到本地文件,因此 URL 格式略有不同。“文件”部分是数据库的名称。对于相对文件路径,这需要三个斜杠。

# sqlite://<nohostname>/<path>
# where <path> is relative:
engine = create_engine("sqlite:///foo.db")

对于绝对文件路径,三个斜杠后跟绝对路径。

# Unix/Mac - 4 initial slashes in total
engine = create_engine("sqlite:////absolute/path/to/foo.db")

# Windows
engine = create_engine("sqlite:///C:\\path\\to\\foo.db")

# Windows alternative using raw string
engine = create_engine(r"sqlite:///C:\path\to\foo.db")

要使用 SQLite :memory: 数据库,请指定一个空 URL。

engine = create_engine("sqlite://")

有关连接到 SQLite 的更多说明,请参阅 SQLite

其他

请参阅 方言,这是所有其他方言文档的顶级页面。

引擎创建 API

对象名称 描述

create_engine(url, **kwargs)

创建一个新的 Engine 实例。

create_mock_engine(url, executor, **kw)

创建一个用于回显 DDL 的“模拟”引擎。

create_pool_from_url(url, **kwargs)

从给定的 url 创建一个池实例。

engine_from_config(configuration[, prefix], **kwargs)

使用配置字典创建一个新的 Engine 实例。

make_url(name_or_url)

给定一个字符串,生成一个新的 URL 实例。

URL

表示用于连接到数据库的 URL 的组件。

function sqlalchemy.create_engine(url: str | _url.URL, **kwargs: Any) Engine

创建一个新的 Engine 实例。

标准调用形式是将 URL 作为第一个位置参数发送,通常是一个字符串,它指示数据库方言和连接参数。

engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")

注意

请查看 数据库 URL 以了解有关编写 URL 字符串的常规指南。特别地,特殊字符(如通常构成密码的一部分的字符)必须进行 URL 编码才能正确解析。

然后,可以添加其他关键字参数来建立对结果 Engine 及其底层 DialectPool 构造的各种选项。

engine = create_engine("mysql+mysqldb://scott:tiger@hostname/dbname",
                            pool_recycle=3600, echo=True)

URL 的字符串形式是 dialect[+driver]://user:password@host/dbname[?key=value..],其中 dialect 是数据库名称,例如 mysqloraclepostgresql 等,而 driver 是 DBAPI 的名称,例如 psycopg2pyodbccx_oracle 等。或者,URL 可以是 URL 的实例。

**kwargs 接受各种选项,这些选项将被路由到相应的组件。参数可能是特定于 Engine 的,也可能是特定于底层 Dialect 的,以及特定于 Pool 的。特定方言还接受特定于该方言的关键字参数。在这里,我们将描述对大多数 create_engine() 用法都通用的参数。

一旦建立,新产生的 Engine 将在调用 Engine.connect() 或其依赖的方法(如 Engine.execute())时,从底层的 Pool 请求连接。而 Pool 在收到此请求时会建立第一个实际的 DBAPI 连接。 create_engine() 调用本身 **不会** 直接建立任何实际的 DBAPI 连接。

参数:
  • connect_args – 一个字典,包含将作为额外的关键字参数直接传递给 DBAPI 的 connect() 方法的选项。请参阅 自定义 DBAPI connect() 参数 / 连接时例程 中的示例。

  • creator

    一个可调用对象,返回一个 DBAPI 连接。此创建函数将传递给底层连接池,并将用于创建所有新的数据库连接。使用此函数会导致 URL 参数中指定的连接参数被绕过。

    此钩子不像更新的 DialectEvents.do_connect() 钩子那样灵活,后者允许对如何建立与数据库的连接进行完全控制,并提供所有 URL 参数和状态信息。

    另请参阅

    DialectEvents.do_connect() - 事件钩子,允许对 DBAPI 连接机制进行完全控制。

    自定义 DBAPI connect() 参数 / 连接时例程

  • echo=False

    如果为 True,则 Engine 将记录所有语句以及其参数列表的 repr() 到默认日志处理程序,默认情况下该处理程序为 sys.stdout,用于输出。如果设置为字符串 "debug",则结果行也将被打印到标准输出。 Engineecho 属性可以随时修改以打开或关闭日志记录;也可以使用标准的 Python logging 模块直接控制日志记录。

    另请参阅

    配置日志记录 - 有关如何配置日志记录的更多详细信息。

  • echo_pool=False

    如果为 True,则连接池将记录信息输出,例如何时连接无效以及何时连接被循环利用到默认日志处理程序,默认情况下该处理程序为 sys.stdout,用于输出。如果设置为字符串 "debug",则日志记录将包括池检出和检入。也可以使用标准的 Python logging 模块直接控制日志记录。

    另请参阅

    配置日志记录 - 有关如何配置日志记录的更多详细信息。

  • empty_in_strategy

    不再使用;SQLAlchemy 现在在所有情况下都使用“空集”行为来处理 IN。

    从版本 1.4 开始弃用: create_engine.empty_in_strategy 关键字已弃用,不再有任何作用。现在,所有 IN 表达式都在语句执行时使用“扩展参数”策略来渲染,该策略渲染一组绑定表达式,或一个“空集” SELECT。

  • enable_from_linting

    默认为 True。如果发现给定的 SELECT 语句包含未链接的 FROM 元素,会导致笛卡尔积,则会发出警告。

    版本 1.4 中的新增内容。

  • execution_options – 将应用于所有连接的字典执行选项。请参阅 Connection.execution_options()

  • future

    使用 2.0 风格的 EngineConnection API。

    从 SQLAlchemy 2.0 开始,此参数仅用于向后兼容,必须保留其默认值 True

    create_engine.future 参数将在随后的 2.x 版本中被弃用,并最终被删除。

    版本 1.4 中的新增内容。

    在版本 2.0 中更改: 所有 Engine 对象都是“future”风格的引擎,不再存在 future=False 的操作模式。

  • hide_parameters

    布尔值,设置为 True 时,SQL 语句参数将不会显示在 INFO 日志中,也不会被格式化为 StatementError 对象的字符串表示形式。

    版本 1.3.8 中的新增内容。

    另请参阅

    配置日志记录 - 有关如何配置日志记录的更多详细信息。

  • implicit_returning=True – 遗留参数,只能设置为 True。在 SQLAlchemy 2.0 中,此参数没有任何作用。为了禁用 ORM 调用的语句的“隐式返回”,请使用 Table.implicit_returning 参数在每个表的基础上进行配置。

  • insertmanyvalues_page_size

    当语句使用“insertmanyvalues”模式时,要格式化为 INSERT 语句的行数。该模式是一种分页形式的批量插入,当使用 executemany 执行时,通常与 RETURNING 结合使用,通常用于许多后端。默认为 1000,但也可能受到特定于方言的限制因素的影响,这些因素可能会在每个语句的基础上覆盖此值。

    版本 2.0 中的新增内容。

  • isolation_level

    可选的隔离级别字符串名称,它将无条件地设置在所有新连接上。隔离级别通常是字符串名称 "SERIALIZABLE""REPEATABLE READ""READ COMMITTED""READ UNCOMMITTED""AUTOCOMMIT" 的子集,具体取决于后端。

    create_engine.isolation_level 参数与 Connection.execution_options.isolation_level 执行选项形成对比,后者可以在单个 Connection 上设置,也可以作为传递给 Engine.execution_options() 的相同参数,在那里可以使用它来创建具有不同隔离级别的多个引擎,这些引擎共享一个公共连接池和方言。

    在版本 2.0 中更改: create_engine.isolation_level 参数已被推广,可以在所有支持隔离级别概念的方言上使用,并且作为更简洁、更直接的配置开关提供,与执行选项形成对比,后者更像是一种临时的编程选项。

  • json_deserializer

    对于支持 JSON 数据类型的方言,这是一个 Python 可调用对象,它将 JSON 字符串转换为 Python 对象。默认情况下,使用 Python json.loads 函数。

    在版本 1.3.7 中更改: SQLite 方言将其从 _json_deserializer 重命名。

  • json_serializer

    对于支持 JSON 数据类型的方言,这是一个 Python 可调用对象,它将渲染给定对象为 JSON。默认情况下,使用 Python json.dumps 函数。

    在版本 1.3.7 中更改: SQLite 方言将此重命名为 _json_serializer

  • label_length=None

    可选的整数值,它将动态生成的列标签的大小限制为该数字字符。如果小于 6,则标签将生成为“_(计数器)”。如果为 None,则使用 dialect.max_identifier_length 的值,该值可能会通过 create_engine.max_identifier_length 参数影响。 create_engine.label_length 的值不能大于 create_engine.max_identfier_length 的值。

  • logging_name

    字符串标识符,它将在“sqlalchemy.engine”记录器中生成的日志记录的“name”字段中使用。默认为对象的 ID 的十六进制字符串。

    另请参阅

    配置日志记录 - 有关如何配置日志记录的更多详细信息。

    Connection.execution_options.logging_token

  • max_identifier_length

    整数;覆盖由方言确定的 max_identifier_length。如果为 None 或零,则无效。这是数据库配置的 SQL 标识符(如表名、列名或标签名)中允许使用的最大字符数。所有方言都自动确定此值,但是如果数据库的新版本发生了变化,但 SQLAlchemy 的方言尚未调整,则可以在这里传递该值。

    版本 1.3.9 中的新增功能。

  • max_overflow=10 – 允许在连接池“溢出”中打开的连接数,即可以在 pool_size 设置(默认为 5)之外打开的连接数。此仅与 QueuePool 一起使用。

  • module=None – 对 Python 模块对象的引用(模块本身,而不是其字符串名称)。指定引擎的方言要使用的替代 DBAPI 模块。每个子方言都引用一个特定的 DBAPI,该 DBAPI 将在第一次连接之前导入。此参数会导致绕过导入,并使用给定的模块。可用于测试 DBAPI 以及将“模拟”DBAPI 实现注入 Engine

  • paramstyle=None – 渲染绑定参数时使用的 paramstyle。此样式默认为 DBAPI 本身推荐的样式,该样式是从 DBAPI 的 .paramstyle 属性中检索的。但是,大多数 DBAPI 都接受多个 paramstyle,特别是可能需要将“命名”paramstyle 更改为“位置”paramstyle,反之亦然。当传递此属性时,它应该是值 "qmark""numeric""named""format""pyformat" 之一,并且应与使用中的 DBAPI 已知支持的参数样式相对应。

  • pool=NonePool 的已构建实例,例如 QueuePool 实例。如果非 None,则此池将直接用作引擎的底层连接池,绕过 URL 参数中存在的任何连接参数。有关手动构建连接池的信息,请参阅 连接池

  • poolclass=NonePool 子类,它将用于使用 URL 中给出的连接参数创建连接池实例。请注意,这与 pool 不同,因为您实际上并没有在此处实例化池,而只是指示要使用哪种类型的池。

  • pool_logging_name

    字符串标识符,它将在“sqlalchemy.pool”记录器中生成的日志记录的“name”字段中使用。默认为对象的 ID 的十六进制字符串。

    另请参阅

    配置日志记录 - 有关如何配置日志记录的更多详细信息。

  • pool_pre_ping

    布尔值,如果为 True,则将启用连接池“预先 ping”功能,该功能会在每次签出时测试连接的活动状态。

    版本 1.2 中的新增功能。

  • pool_size=5 – 连接池中要保持打开的连接数。此与 QueuePool 以及 SingletonThreadPool 一起使用。使用 QueuePoolpool_size 设置为 0 表示无限制;要禁用池,请将 poolclass 设置为 NullPool

  • pool_recycle=-1

    此设置会导致池在经过给定秒数后回收连接。它默认为 -1,或无超时。例如,设置为 3600 表示连接将在 1 小时后回收。请注意,特别是 MySQL 将在连接上未检测到任何活动 8 小时后自动断开连接(尽管这可以通过 MySQLDB 连接本身和服务器配置进行配置)。

    另请参阅

    设置池回收

  • pool_reset_on_return='rollback'

    设置底层 Pool.reset_on_return 对象的 Pool 参数,该参数可以设置为值 "rollback""commit"None

    另请参阅

    返回时重置

  • pool_timeout=30

    在放弃从池中获取连接之前要等待的秒数。此仅与 QueuePool 一起使用。这可以是浮点数,但会受到 Python 时间函数的限制,这些函数在几十毫秒内可能不可靠。

  • pool_use_lifo=False

    QueuePool 检索连接时使用 LIFO(后进先出)而不是 FIFO(先进先出)。使用 LIFO,服务器端超时方案可以减少在非高峰使用期间使用的连接数。在规划服务器端超时时,请确保使用回收或预先 ping 策略来优雅地处理陈旧连接。

    版本 1.3 中的新增功能。

  • plugins

    要加载的插件名称的字符串列表。有关背景信息,请参阅 CreateEnginePlugin

    版本 1.2.3 中的新增功能。

  • query_cache_size

    用于缓存查询的 SQL 字符串形式的缓存大小。设置为零以禁用缓存。

    当缓存大小达到 N * 1.5 时,缓存将从其最近最少使用的项目中修剪。默认为 500,这意味着缓存将在填充时始终存储至少 500 个 SQL 语句,并且将增长到 750 个项目,此时它将通过删除 250 个最近最少使用的项目修剪回 500 个项目。

    缓存是在每个语句的基础上完成的,方法是生成一个表示语句结构的缓存键,然后仅当该键不存在于缓存中时才为当前方言生成字符串 SQL。所有语句都支持缓存,但是某些功能(例如包含大量参数的 INSERT)将有意绕过缓存。SQL 日志记录将指示每个语句的统计信息,无论它是否从缓存中拉取。

    注意

    一些与工作单元持久性相关的 ORM 函数以及一些属性加载策略将在主缓存之外使用单独的每个映射器缓存。

    另请参阅

    SQL 编译缓存

    版本 1.4 中的新增内容。

  • use_insertmanyvalues

    默认情况下为 True,默认情况下对 INSERT..RETURNING 语句使用“insertmanyvalues”执行样式。

    版本 2.0 中的新增内容。

function sqlalchemy.engine_from_config(configuration: Dict[str, Any], prefix: str = 'sqlalchemy.', **kwargs: Any) Engine

使用配置字典创建一个新的 Engine 实例。

该字典通常由配置文件生成。

engine_from_config() 的感兴趣键应带前缀,例如 sqlalchemy.urlsqlalchemy.echo 等。“prefix” 参数指示要搜索的前缀。每个匹配的键(在去除前缀后)都将被视为对 create_engine() 调用时相应的关键字参数。

唯一必需的键是(假设默认前缀)sqlalchemy.url,它提供 数据库 URL

一组选定的关键字参数将根据字符串值“强制”转换为它们的预期类型。参数集可以使用 engine_config_types 访问器按方言扩展。

参数:
  • configuration – 字典(通常由配置文件生成,但这不是必需的)。其键以“prefix” 值开头的项目将去掉该前缀,然后传递给 create_engine()

  • prefix – 与“configuration” 中的键匹配并从键中去除的前缀。

  • kwargsengine_from_config() 本身的每个关键字参数都将覆盖从“configuration” 字典中获取的对应项目。关键字参数不应带前缀。

function sqlalchemy.create_mock_engine(url: str | URL, executor: Any, **kw: Any) MockConnection

创建一个用于回显 DDL 的“模拟”引擎。

这是一个用于调试或存储 MetaData.create_all() 及其相关方法生成的 DDL 序列输出的实用函数。

该函数接受一个仅用于确定要使用的方言类型的 URL,以及一个“executor” 可调用函数,该函数将接收一个 SQL 表达式对象和参数,然后可以回显或以其他方式打印。执行程序的返回值不处理,并且引擎不允许调用常规字符串语句,因此仅对发送到数据库而不接收任何结果的 DDL 有用。

例如:

from sqlalchemy import create_mock_engine

def dump(sql, *multiparams, **params):
    print(sql.compile(dialect=engine.dialect))

engine = create_mock_engine('postgresql+psycopg2://', dump)
metadata.create_all(engine, checkfirst=False)
参数:
  • url – 通常只需要包含数据库后端名称的字符串 URL。

  • executor – 一个可调用对象,接收参数 sql*multiparams**paramssql 参数通常是 ExecutableDDLElement 的实例,可以使用 ExecutableDDLElement.compile() 将其编译为字符串。

版本 1.4 中的新内容: - create_mock_engine() 函数取代了之前使用 create_engine() 的“模拟”引擎策略。

function sqlalchemy.engine.make_url(name_or_url: str | URL) URL

给定一个字符串,生成一个新的 URL 实例。

URL 的格式通常遵循 RFC-1738,但有一些例外,包括“方案”部分内接受下划线,而不是连字符或句点。

如果传递了 URL 对象,则按原样返回。

另请参阅

数据库 URL

function sqlalchemy.create_pool_from_url(url: str | URL, **kwargs: Any) Pool

从给定的 url 创建一个池实例。

如果没有提供 poolclass,则使用 URL 中指定的方言选择使用的池类。

传递给 create_pool_from_url() 的参数与传递给 create_engine() 函数的池参数相同。

版本 2.0.10 中的新内容。

class sqlalchemy.engine.URL

表示用于连接到数据库的 URL 的组件。

URL 通常由完全格式化的 URL 字符串构造,其中 make_url() 函数由 create_engine() 函数在内部使用,以将 URL 字符串解析为其各个组件,然后使用这些组件构造一个新的 URL 对象。从格式化的 URL 字符串解析时,解析格式通常遵循 RFC-1738,但有一些例外。

也可以直接生成 URL 对象,方法是使用 make_url() 函数使用完整格式化的 URL 字符串,或者使用 URL.create() 构造函数,以便在给定各个字段的情况下以编程方式构造 URL。生成的 URL 对象可以直接传递给 create_engine(),代替字符串参数,这将绕过在引擎创建过程中使用 make_url()

版本 1.4 中的变更: URL 对象现在是不可变对象。 要创建 URL,请使用 make_url()URL.create() 函数/方法。 要修改 URL,请使用 URL.set()URL.update_query_dict() 等方法以返回包含修改的新 URL 对象。 有关此更改的说明,请参阅 URL 对象现在是不可变的

另请参阅

数据库 URL

URL 包含以下属性

类签名

class sqlalchemy.engine.URL (builtins.tuple)

classmethod sqlalchemy.engine.URL.create(drivername: str, username: str | None = None, password: str | None = None, host: str | None = None, port: int | None = None, database: str | None = None, query: Mapping[str, Sequence[str] | str] = {}) URL

创建一个新的 URL 对象。

另请参阅

数据库 URL

参数:
  • drivername – 数据库后端的名称。 此名称将对应于 sqlalchemy/databases 中的模块或第三方插件。

  • username – 用户名。

  • password

    数据库密码。 通常是字符串,但也可能是可以通过 str() 转换为字符串的对象。

    注意

    密码字符串在作为 URL.create() 的参数传递时,不应该 进行 URL 编码;该字符串应包含与键入完全相同的密码字符。

    注意

    每个 Engine 对象的密码生成对象将仅被转换为字符串一次。 有关每个连接的动态密码生成,请参阅 生成动态身份验证令牌

  • host – 主机的名称。

  • port – 端口号。

  • database – 数据库名称。

  • query – 一个字典,包含在连接时传递给方言和/或 DBAPI 的字符串键和字符串值。 要将非字符串参数直接传递给 Python DBAPI,请使用 create_engine.connect_args 参数传递给 create_engine()。 有关始终为字符串 -> 字符串列表的字典,请参阅 URL.normalized_query

返回值:

新的 URL 对象。

版本 1.4 中的新增功能: URL 对象现在是不可变命名元组。 此外,query 字典也是不可变的。 要创建 URL,请使用 make_url()URL.create() 函数/方法。 要修改 URL,请使用 URL.set()URL.update_query() 方法。

attribute sqlalchemy.engine.URL.database: str | None

数据库名称

方法 sqlalchemy.engine.URL.difference_update_query(names: Iterable[str]) URL

URL.query 字典中删除给定的名称,返回新的 URL

例如:

url = url.difference_update_query(['foo', 'bar'])

等同于使用 URL.set() 如下

url = url.set(
    query={
        key: url.query[key]
        for key in set(url.query).difference(['foo', 'bar'])
    }
)

版本 1.4 中的新增内容。

属性 sqlalchemy.engine.URL.drivername: str

数据库后端和驱动程序名称,例如 postgresql+psycopg2

方法 sqlalchemy.engine.URL.get_backend_name() str

返回后端名称。

这是对应于正在使用的数据库后端的名称,是 URL.drivername 中加号左侧的部分。

方法 sqlalchemy.engine.URL.get_dialect(_is_async: bool = False) Type[Dialect]

返回与该 URL 的驱动程序名称相对应的 SQLAlchemy Dialect 类。

方法 sqlalchemy.engine.URL.get_driver_name() str

返回后端名称。

这是对应于正在使用的 DBAPI 驱动程序的名称,是 URL.drivername 中加号右侧的部分。

如果 URL.drivername 不包含加号,那么将导入此 URL 的默认 Dialect 以获取驱动程序名称。

属性 sqlalchemy.engine.URL.host: str | None

主机名或 IP 号码。对于某些驱动程序,也可能是一个数据源名称。

属性 sqlalchemy.engine.URL.normalized_query

返回 URL.query 字典,其中值规范化为序列。

由于 URL.query 字典可能包含字符串值或字符串值序列以区分在查询字符串中多次指定的参数,因此需要通用处理多个参数的代码将希望使用此属性,以便所有存在的参数都以序列的形式呈现。灵感来自 Python 的 urllib.parse.parse_qs 函数。例如

>>> from sqlalchemy.engine import make_url
>>> url = make_url("postgresql+psycopg2://user:pass@host/dbname?alt_host=host1&alt_host=host2&ssl_cipher=%2Fpath%2Fto%2Fcrt")
>>> url.query
immutabledict({'alt_host': ('host1', 'host2'), 'ssl_cipher': '/path/to/crt'})
>>> url.normalized_query
immutabledict({'alt_host': ('host1', 'host2'), 'ssl_cipher': ('/path/to/crt',)})
属性 sqlalchemy.engine.URL.password: str | None

密码,通常是字符串,但也可能是任何具有 __str__() 方法的对象。

属性 sqlalchemy.engine.URL.port: int | None

整数端口号

属性 sqlalchemy.engine.URL.query: immutabledict[str, Tuple[str, ...] | str]

表示查询字符串的不可变映射。包含字符串作为键,以及字符串或字符串元组作为值,例如

   >>> from sqlalchemy.engine import make_url
   >>> url = make_url("postgresql+psycopg2://user:pass@host/dbname?alt_host=host1&alt_host=host2&ssl_cipher=%2Fpath%2Fto%2Fcrt")
   >>> url.query
   immutabledict({'alt_host': ('host1', 'host2'), 'ssl_cipher': '/path/to/crt'})

To create a mutable copy of this mapping, use the ``dict`` constructor::

   mutable_query_opts = dict(url.query)

另请参阅

URL.normalized_query - 将所有值规范化为序列以进行一致处理

用于更改 URL.query 内容的方法

URL.update_query_dict()

URL.update_query_string()

URL.update_query_pairs()

URL.difference_update_query()

方法 sqlalchemy.engine.URL.render_as_string(hide_password: bool = True) str

将此 URL 对象呈现为字符串。

当使用 __str__()__repr__() 方法时,此方法用于。该方法直接包含其他选项。

参数:

hide_password – 默认值为 True。除非将此设置为 False,否则密码不会显示在字符串中。

method sqlalchemy.engine.URL.set(drivername: str | None = None, username: str | None = None, password: str | None = None, host: str | None = None, port: int | None = None, database: str | None = None, query: Mapping[str, Sequence[str] | str] | None = None) URL

返回一个新的 URL 对象,其中包含修改。

如果值不为 None,则使用这些值。若要显式将值设置为 None,请使用从 namedtuple 适配的 URL._replace() 方法。

参数:
  • drivername – 新的驱动程序名称

  • username – 新的用户名

  • password – 新的密码

  • host – 新的主机名

  • port – 新的端口

  • query – 新的查询参数,传递一个字符串键到字符串或字符串序列值的字典。完全替换之前的参数列表。

返回值:

新的 URL 对象。

版本 1.4 中的新增内容。

method sqlalchemy.engine.URL.translate_connect_args(names: List[str] | None = None, **kw: Any) Dict[str, Any]

将 url 属性转换为连接参数字典。

将此 url 的属性 (hostdatabaseusernamepasswordport) 作为普通字典返回。默认情况下,属性名称用作键。未设置或为假的值将从最终字典中省略。

参数:
  • **kw – 可选,url 属性的替代键名。

  • names – 已弃用。与基于关键字的替代名称用途相同,但将名称与原始位置相关联。

method sqlalchemy.engine.URL.update_query_dict(query_parameters: Mapping[str, str | List[str]], append: bool = False) URL

返回一个新的 URL 对象,其 URL.query 参数字典已由给定字典更新。

该字典通常包含字符串键和字符串值。为了表示多次表达的查询参数,请传递一个字符串值的序列。

例如:

>>> from sqlalchemy.engine import make_url
>>> url = make_url("postgresql+psycopg2://user:pass@host/dbname")
>>> url = url.update_query_dict({"alt_host": ["host1", "host2"], "ssl_cipher": "/path/to/crt"})
>>> str(url)
'postgresql+psycopg2://user:pass@host/dbname?alt_host=host1&alt_host=host2&ssl_cipher=%2Fpath%2Fto%2Fcrt'
参数:
  • query_parameters – 一个字典,其中包含字符串键和值为字符串或字符串序列的值。

  • append – 如果为 True,则不会删除现有查询字符串中的参数;新的参数将添加到现有参数中。如果保留其默认值 False,则给定查询参数中存在的键将替换现有查询字符串中的键。

版本 1.4 中的新增内容。

method sqlalchemy.engine.URL.update_query_pairs(key_value_pairs: Iterable[Tuple[str, str | List[str]]], append: bool = False) URL

返回一个新的 URL 对象,其 URL.query 参数字典已由给定的键/值对序列更新

例如:

>>> from sqlalchemy.engine import make_url
>>> url = make_url("postgresql+psycopg2://user:pass@host/dbname")
>>> url = url.update_query_pairs([("alt_host", "host1"), ("alt_host", "host2"), ("ssl_cipher", "/path/to/crt")])
>>> str(url)
'postgresql+psycopg2://user:pass@host/dbname?alt_host=host1&alt_host=host2&ssl_cipher=%2Fpath%2Fto%2Fcrt'
参数:
  • key_value_pairs – 包含两个字符串的元组的序列。

  • append – 如果为 True,则不会删除现有查询字符串中的参数;新的参数将添加到现有参数中。如果保留其默认值 False,则给定查询参数中存在的键将替换现有查询字符串中的键。

版本 1.4 中的新增内容。

method sqlalchemy.engine.URL.update_query_string(query_string: str, append: bool = False) URL

返回一个新的 URL 对象,其 URL.query 参数字典已由给定的查询字符串更新。

例如:

>>> from sqlalchemy.engine import make_url
>>> url = make_url("postgresql+psycopg2://user:pass@host/dbname")
>>> url = url.update_query_string("alt_host=host1&alt_host=host2&ssl_cipher=%2Fpath%2Fto%2Fcrt")
>>> str(url)
'postgresql+psycopg2://user:pass@host/dbname?alt_host=host1&alt_host=host2&ssl_cipher=%2Fpath%2Fto%2Fcrt'
参数:
  • query_string – 一个 URL 编码的查询字符串,不包括问号。

  • append – 如果为 True,则不会删除现有查询字符串中的参数;新参数将添加到现有参数中。如果保留为默认值 False,则给定查询参数中存在的键将替换现有查询字符串中的键。

版本 1.4 中的新增内容。

attribute sqlalchemy.engine.URL.username: str | None

用户名字符串

连接池

当调用 connect()execute() 方法时,Engine 会向连接池请求一个连接。默认的连接池,QueuePool,将在需要时打开到数据库的连接。当执行并发语句时,QueuePool 将将其连接池扩展到默认大小为五,并允许默认的“溢出”为十。由于 Engine 本质上是连接池的“主基地”,因此,你应该在应用程序中为每个已建立的数据库保留一个 Engine,而不是为每个连接创建一个新的。

注意

QueuePool 默认情况下不适用于 SQLite 引擎。有关 SQLite 连接池使用的详细信息,请参阅 SQLite

有关连接池的更多信息,请参阅 连接池

自定义 DBAPI connect() 参数 / 连接时例程

对于需要特殊连接方法的情况,在绝大多数情况下,最合适的做法是在 create_engine() 级别的几个钩子中使用其中一个来自定义此过程。这些将在以下小节中介绍。

传递给 dbapi.connect() 的特殊关键字参数

所有 Python DBAPI 除了连接的基本要素之外,还接受其他参数。常见参数包括用于指定字符集编码和超时值的参数;更复杂的数据包括特殊的 DBAPI 常量和对象以及 SSL 子参数。在不增加复杂性的情况下,传递这些参数有两种基本方法。

将参数添加到 URL 查询字符串

简单字符串值,以及一些数值和布尔标志,通常可以在 URL 的查询字符串中直接指定。一个常见的例子是 DBAPI 接受一个名为 encoding 的参数来指定字符编码,例如大多数 MySQL DBAPI

engine = create_engine("mysql+pymysql://user:pass@host/test?charset=utf8mb4")

使用查询字符串的优点是,可以在配置文件中以一种可移植到 URL 中指定的 DBAPI 的方式指定其他 DBAPI 选项。通过此级别传递的具体参数因 SQLAlchemy 方言而异。有些方言将所有参数作为字符串传递,而另一些则会解析特定数据类型并将参数移动到其他位置,例如驱动程序级别的 DSN 和连接字符串。由于这方面的每个方言行为目前都各不相同,因此应该查阅正在使用的特定方言的方言文档,以查看特定参数是否在此级别上支持。

提示

显示给定 URL 传递给 DBAPI 的确切参数的一般方法是,使用 Dialect.create_connect_args() 方法直接执行以下操作

>>> from sqlalchemy import create_engine
>>> engine = create_engine(
...     "mysql+pymysql://some_user:some_pass@some_host/test?charset=utf8mb4"
... )
>>> args, kwargs = engine.dialect.create_connect_args(engine.url)
>>> args, kwargs
([], {'host': 'some_host', 'database': 'test', 'user': 'some_user', 'password': 'some_pass', 'charset': 'utf8mb4', 'client_flag': 2})

上面的 args, kwargs 对通常作为 dbapi.connect(*args, **kwargs) 传递给 DBAPI。

使用 connect_args 字典参数

一个更通用的系统,用于将任何参数传递给 dbapi.connect() 函数,并保证始终传递所有参数,是 create_engine.connect_args 字典参数。这可用于方言在添加到查询字符串时未处理的参数,以及必须将特殊子结构或对象传递给 DBAPI 的情况。有时,只是某个特定标志必须作为 True 符号发送,而 SQLAlchemy 方言并不知道此关键字参数以将其从 URL 中呈现的字符串形式转换。下面说明了使用 psycopg2 “连接工厂”来替换连接的底层实现

engine = create_engine(
    "postgresql+psycopg2://user:pass@hostname/dbname",
    connect_args={"connection_factory": MyConnectionFactory},
)

另一个例子是 pyodbc 的“timeout”参数

engine = create_engine(
    "mssql+pyodbc://user:pass@sqlsrvr?driver=ODBC+Driver+13+for+SQL+Server",
    connect_args={"timeout": 30},
)

上面的例子还说明了,URL “查询字符串”参数和 create_engine.connect_args 可以同时使用;在 pyodbc 的情况下,“driver”关键字在 URL 中具有特殊含义。

控制如何将参数传递给 DBAPI connect() 函数

除了操作传递给 connect() 的参数之外,我们还可以使用 DialectEvents.do_connect() 事件钩子来进一步自定义 DBAPI connect() 函数本身的调用方式。此钩子传递给方言将发送给 connect() 的完整 *args, **kwargs。然后可以就地修改这些集合以更改它们的用法

from sqlalchemy import event

engine = create_engine("postgresql+psycopg2://user:pass@hostname/dbname")


@event.listens_for(engine, "do_connect")
def receive_do_connect(dialect, conn_rec, cargs, cparams):
    cparams["connection_factory"] = MyConnectionFactory

生成动态身份验证令牌

DialectEvents.do_connect() 也是动态插入身份验证令牌(可能在 Engine 的生命周期内发生变化)的理想方式。例如,如果令牌由 get_authentication_token() 生成并以 token 参数传递给 DBAPI,则可以按如下方式实现

from sqlalchemy import event

engine = create_engine("postgresql+psycopg2://user@hostname/dbname")


@event.listens_for(engine, "do_connect")
def provide_token(dialect, conn_rec, cargs, cparams):
    cparams["token"] = get_authentication_token()

另请参阅

使用访问令牌连接到数据库 - 一个涉及 SQL Server 的更具体的示例

连接后修改 DBAPI 连接,或在连接后运行命令

对于 SQLAlchemy 创建的没有问题的 DBAPI 连接,但我们想在实际使用之前修改已完成的连接,例如设置特殊标志或运行某些命令,PoolEvents.connect() 事件钩子是最合适的钩子。此钩子会在创建每个新连接时调用,在 SQLAlchemy 使用它之前调用

from sqlalchemy import event

engine = create_engine("postgresql+psycopg2://user:pass@hostname/dbname")


@event.listens_for(engine, "connect")
def connect(dbapi_connection, connection_record):
    cursor_obj = dbapi_connection.cursor()
    cursor_obj.execute("SET some session variables")
    cursor_obj.close()

完全替换 DBAPI connect() 函数

最后,DialectEvents.do_connect() 事件钩子还可以让我们通过建立连接并返回连接来完全接管连接过程

from sqlalchemy import event

engine = create_engine("postgresql+psycopg2://user:pass@hostname/dbname")


@event.listens_for(engine, "do_connect")
def receive_do_connect(dialect, conn_rec, cargs, cparams):
    # return the new DBAPI connection with whatever we'd like to
    # do
    return psycopg2.connect(*cargs, **cparams)

DialectEvents.do_connect() 挂钩取代了之前的 create_engine.creator 挂钩,后者仍然可用。 DialectEvents.do_connect() 的优势在于,它将从 URL 解析的完整参数传递给用户定义的函数,而 create_engine.creator 则不会这样做。

配置日志记录

Python 的标准 logging 模块用于实现 SQLAlchemy 的信息和调试日志输出。这使 SQLAlchemy 的日志记录能够以标准方式与其他应用程序和库集成。 create_engine.echocreate_engine.echo_pool 两个参数在 create_engine() 中存在,它们允许将日志记录立即输出到 sys.stdout 中,以便进行本地开发;这些参数最终与下面描述的常规 Python 记录器进行交互。

本节假设您熟悉上面链接的日志记录模块。SQLAlchemy 执行的所有日志记录都在 sqlalchemy 命名空间下,如 logging.getLogger('sqlalchemy') 所用。当配置了日志记录(例如通过 logging.basicConfig())时,可以打开的 SA 记录器的一般命名空间如下所示

  • sqlalchemy.engine - 控制 SQL 回显。设置为 logging.INFO 以输出 SQL 查询,设置为 logging.DEBUG 以输出查询 + 结果集。这些设置等同于 create_engine.echo 上的 echo=Trueecho="debug"

  • sqlalchemy.pool - 控制连接池日志记录。设置为 logging.INFO 以记录连接失效和回收事件;设置为 logging.DEBUG 以另外记录所有池签入和签出。这些设置等同于 create_engine.echo_pool 上的 pool_echo=Truepool_echo="debug"

  • sqlalchemy.dialects - 控制 SQL 方言的自定义日志记录,在特定方言中使用日志记录的范围内,通常很少。

  • sqlalchemy.orm - 控制各种 ORM 函数的日志记录,在 ORM 中使用日志记录的范围内,通常很少。设置为 logging.INFO 以记录关于映射器配置的一些顶级信息。

例如,要使用 Python 日志记录而不是 echo=True 标志来记录 SQL 查询

import logging

logging.basicConfig()
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)

默认情况下,整个 sqlalchemy 命名空间中的日志级别设置为 logging.WARN,因此即使在已启用日志记录的应用程序中,也不会执行任何日志操作。

注意

SQLAlchemy Engine 通过仅在当前日志级别检测为 logging.INFOlogging.DEBUG 时才发出日志语句来节省 Python 函数调用开销。它仅在从连接池中获取新连接时才检查此级别。因此,当更改已运行应用程序的日志记录配置时,任何当前活动的 Connection,或者更常见的是在事务中活动的 Session 对象,都不会根据新配置记录任何 SQL,直到获取新 Connection 为止(对于 Session 而言,这发生在当前事务结束并开始新的事务之后)。

关于回显标志的更多信息

如前所述,create_engine.echocreate_engine.echo_pool 参数是立即将日志记录到 sys.stdout 的快捷方式。

>>> from sqlalchemy import create_engine, text
>>> e = create_engine("sqlite://", echo=True, echo_pool="debug")
>>> with e.connect() as conn:
...     print(conn.scalar(text("select 'hi'")))
2020-10-24 12:54:57,701 DEBUG sqlalchemy.pool.impl.SingletonThreadPool Created new connection <sqlite3.Connection object at 0x7f287819ac60>
2020-10-24 12:54:57,701 DEBUG sqlalchemy.pool.impl.SingletonThreadPool Connection <sqlite3.Connection object at 0x7f287819ac60> checked out from pool
2020-10-24 12:54:57,702 INFO sqlalchemy.engine.Engine select 'hi'
2020-10-24 12:54:57,702 INFO sqlalchemy.engine.Engine ()
hi
2020-10-24 12:54:57,703 DEBUG sqlalchemy.pool.impl.SingletonThreadPool Connection <sqlite3.Connection object at 0x7f287819ac60> being returned to pool
2020-10-24 12:54:57,704 DEBUG sqlalchemy.pool.impl.SingletonThreadPool Connection <sqlite3.Connection object at 0x7f287819ac60> rollback-on-return

使用这些标志大致相当于

import logging

logging.basicConfig()
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
logging.getLogger("sqlalchemy.pool").setLevel(logging.DEBUG)

重要的是要注意,这两个标志独立于任何现有的日志记录配置工作,并且将无条件地使用 logging.basicConfig()。这会导致它除了任何现有的日志记录器配置之外被配置。因此,当显式配置日志记录时,确保始终将所有回显标志设置为 False,以避免出现重复的日志行。

设置日志记录名称

例如 EnginePool 这样的实例的日志记录器名称默认使用截断的十六进制标识符字符串。要将其设置为特定名称,请使用 create_engine.logging_namecreate_engine.pool_logging_name 以及 sqlalchemy.create_engine();该名称将附加到日志记录名称 sqlalchemy.engine.Engine

>>> import logging
>>> from sqlalchemy import create_engine
>>> from sqlalchemy import text
>>> logging.basicConfig()
>>> logging.getLogger("sqlalchemy.engine.Engine.myengine").setLevel(logging.INFO)
>>> e = create_engine("sqlite://", logging_name="myengine")
>>> with e.connect() as conn:
...     conn.execute(text("select 'hi'"))
2020-10-24 12:47:04,291 INFO sqlalchemy.engine.Engine.myengine select 'hi'
2020-10-24 12:47:04,292 INFO sqlalchemy.engine.Engine.myengine ()

提示

create_engine.logging_namecreate_engine.pool_logging_name 参数也可以与 create_engine.echocreate_engine.echo_pool 一起使用。但是,如果其他引擎在回显标志设置为 True 且没有日志记录名称的情况下创建,则会发生不可避免的双重日志记录情况。这是因为将自动为 sqlalchemy.engine.Engine 添加处理程序,该处理程序将记录无名引擎和具有日志记录名称的引擎的日志消息。例如

from sqlalchemy import create_engine, text

e1 = create_engine("sqlite://", echo=True, logging_name="myname")
with e1.begin() as conn:
    conn.execute(text("SELECT 1"))

e2 = create_engine("sqlite://", echo=True)
with e2.begin() as conn:
    conn.execute(text("SELECT 2"))

with e1.begin() as conn:
    conn.execute(text("SELECT 3"))

上述场景将双重记录 SELECT 3。要解决此问题,请确保所有引擎都设置了 logging_name,或者在不使用 create_engine.echocreate_engine.echo_pool 的情况下使用显式记录器/处理程序设置。

设置每个连接/子引擎令牌

版本 1.4.0b2 中的新增功能。

虽然日志记录名称适合在长寿的 Engine 对象上建立,但它不够灵活,无法容纳任意数量的名称列表,以用于在日志消息中跟踪各个连接和/或事务。

对于此用例,ConnectionResult 对象生成的日志消息本身可能会使用其他令牌(例如事务或请求标识符)进行扩展。 Connection.execution_options.logging_token 参数接受一个字符串参数,可用于建立每个连接跟踪令牌

>>> from sqlalchemy import create_engine
>>> e = create_engine("sqlite://", echo="debug")
>>> with e.connect().execution_options(logging_token="track1") as conn:
...     conn.execute(text("select 1")).all()
2021-02-03 11:48:45,754 INFO sqlalchemy.engine.Engine [track1] select 1
2021-02-03 11:48:45,754 INFO sqlalchemy.engine.Engine [track1] [raw sql] ()
2021-02-03 11:48:45,754 DEBUG sqlalchemy.engine.Engine [track1] Col ('1',)
2021-02-03 11:48:45,755 DEBUG sqlalchemy.engine.Engine [track1] Row (1,)

Connection.execution_options.logging_token 参数也可以通过 create_engine.execution_optionsEngine.execution_options() 在引擎或子引擎上建立。这可能有助于将不同的日志记录令牌应用于应用程序的不同组件,而无需创建新的引擎

>>> from sqlalchemy import create_engine
>>> e = create_engine("sqlite://", echo="debug")
>>> e1 = e.execution_options(logging_token="track1")
>>> e2 = e.execution_options(logging_token="track2")
>>> with e1.connect() as conn:
...     conn.execute(text("select 1")).all()
2021-02-03 11:51:08,960 INFO sqlalchemy.engine.Engine [track1] select 1
2021-02-03 11:51:08,960 INFO sqlalchemy.engine.Engine [track1] [raw sql] ()
2021-02-03 11:51:08,960 DEBUG sqlalchemy.engine.Engine [track1] Col ('1',)
2021-02-03 11:51:08,961 DEBUG sqlalchemy.engine.Engine [track1] Row (1,)

>>> with e2.connect() as conn:
...     conn.execute(text("select 2")).all()
2021-02-03 11:52:05,518 INFO sqlalchemy.engine.Engine [track2] Select 1
2021-02-03 11:52:05,519 INFO sqlalchemy.engine.Engine [track2] [raw sql] ()
2021-02-03 11:52:05,520 DEBUG sqlalchemy.engine.Engine [track2] Col ('1',)
2021-02-03 11:52:05,520 DEBUG sqlalchemy.engine.Engine [track2] Row (1,)

隐藏参数

Engine 发出的日志还包含特定语句的 SQL 参数摘录。为了防止这些参数出于隐私目的被记录,请启用 create_engine.hide_parameters 标志。

>>> e = create_engine("sqlite://", echo=True, hide_parameters=True)
>>> with e.connect() as conn:
...     conn.execute(text("select :some_private_name"), {"some_private_name": "pii"})
2020-10-24 12:48:32,808 INFO sqlalchemy.engine.Engine select ?
2020-10-24 12:48:32,808 INFO sqlalchemy.engine.Engine [SQL parameters hidden due to hide_parameters=True]