SqlAlchemy 2.0 中文文件(二十)
原文:
docs.sqlalchemy.org/en/20/contents.html
插入,更新,刪除
原文:
docs.sqlalchemy.org/en/20/core/dml.html
INSERT、UPDATE 和 DELETE 語句是基於從 UpdateBase
開始的層次結構構建的。Insert
和 Update
構造基於中介 ValuesBase
構建。
DML 基礎建構函式
最頂層的“INSERT”,“UPDATE”,“DELETE”建構函式。
物件名稱 | 描述 |
---|---|
delete(table) | 構造 Delete 物件。 |
insert(table) | 構造 Insert 物件。 |
update(table) | 構造一個 Update 物件。 |
function sqlalchemy.sql.expression.delete(table: _DMLTableArgument) → Delete
構造 Delete
物件。
例如:
from sqlalchemy import delete
stmt = (
delete(user_table).
where(user_table.c.id == 5)
)
相似的功能也可以透過 TableClause.delete()
方法在 Table
上使用。
引數:
table – 要從中刪除行的表。
參見
使用 UPDATE 和 DELETE 語句 - 在 SQLAlchemy 統一教程 中
function sqlalchemy.sql.expression.insert(table: _DMLTableArgument) → Insert
構造一個 Insert
物件。
例如:
from sqlalchemy import insert
stmt = (
insert(user_table).
values(name='username', fullname='Full Username')
)
相似的功能也可以透過 TableClause.insert()
方法在 Table
上使用。
參見
使用 INSERT 語句 - 在 SQLAlchemy 統一教程 中
引數:
-
table
–TableClause
插入的主題。 -
values
– 要插入的值的集合;參見Insert.values()
以獲取這裡允許的格式描述。可以完全省略;Insert
構造也會根據傳遞給Connection.execute()
的引數在執行時動態渲染 VALUES 子句。 -
inline
– 如果為 True,則不會嘗試檢索 SQL 生成的預設值以在語句中提供;特別是,這允許 SQL 表示式在語句中“內聯”渲染,而無需事先預先執行它們;對於支援“返回”的後端,這將關閉語句的“隱式返回”功能。
如果同時存在insert.values
和編譯時繫結引數,則編譯時繫結引數將在每個鍵的基礎上覆蓋insert.values
中指定的資訊。
Insert.values
中的鍵可以是Column
物件或它們的字串識別符號。每個鍵可以引用以下之一:
-
一個字面資料值(即字串,數字等);
-
一個 Column 物件;
-
一個 SELECT 語句。
如果指定了引用此INSERT
語句表的SELECT
語句,則該語句將與INSERT
語句相關聯。
另請參閱
使用 INSERT 語句 - 在 SQLAlchemy 統一教程中
function sqlalchemy.sql.expression.update(table: _DMLTableArgument) → Update
構造一個Update
物件。
例如:
from sqlalchemy import update
stmt = (
update(user_table).
where(user_table.c.id == 5).
values(name='user #5')
)
透過TableClause.update()
方法在Table
上也可以實現類似功能。
引數:
table – 代表要更新的資料庫表的Table
物件。
另請參閱
使用 UPDATE 和 DELETE 語句 - 在 SQLAlchemy 統一教程中
DML 類文件建構函式
DML 基礎建構函式的類建構函式文件。
物件名稱 | 描述 |
---|---|
Delete | 代表一個 DELETE 構造。 |
插入 | 代表一個插入操作。 |
更新 | 代表一個更新操作。 |
UpdateBase | 形成 INSERT 、UPDATE 和 DELETE 語句的基礎。 |
ValuesBase | 為 ValuesBase.values() 提供對 INSERT 和 UPDATE 構造的支援。 |
class sqlalchemy.sql.expression.Delete
代表一個刪除操作。
使用 delete()
函式建立 Delete
物件。
成員
where(), returning()
類簽名
類 sqlalchemy.sql.expression.Delete
(sqlalchemy.sql.expression.DMLWhereBase
, sqlalchemy.sql.expression.UpdateBase
)
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
繼承自 DMLWhereBase.where()
方法的 DMLWhereBase
返回一個新構造,其中給定的表示式已新增到其 WHERE 子句中,如果有的話,透過 AND 連線到現有子句。
Update.where()
和 Delete.where()
都支援多表形式,包括特定於資料庫的 UPDATE...FROM
和 DELETE..USING
。對於不支援多表的後端,使用多表的跨後端方法是利用相關子查詢。檢視下面連結的教程部分以獲取示例。
另請參見
相關更新
UPDATE..FROM
多表刪除
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
繼承自 UpdateBase.returning()
方法的 UpdateBase
為該語句新增一個 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
該方法可以多次呼叫,以將新條目新增到要返回的表示式列表中。
版本 1.4.0b2 中的新功能:該方法可以多次呼叫,以將新條目新增到要返回的表示式列表中。
給定的列表示式集合應來源於 INSERT、UPDATE 或 DELETE 的目標表。雖然 Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,RETURNING 子句或資料庫等效項將在語句中呈現。對於 INSERT 和 UPDATE,值是新插入/更新的值。對於 DELETE,值是刪除的行的值。
在執行時,要返回的列的值透過結果集可用,並可使用CursorResult.fetchone()
等進行迭代。對於不原生支援返回值的 DBAPI(即 cx_oracle),SQLAlchemy 將在結果級別上近似此行為,以便提供合理的行為中立性。
請注意,並非所有資料庫/DBAPI 支援 RETURNING。對於沒有支援的後端,在編譯和/或執行時會引發異常。對於支援它的後端,跨後端的功能差異很大,包括對 executemany() 和其他返回多行的語句的限制。請閱讀正在使用的資料庫的文件註釋,以確定 RETURNING 的可用性。
引數:
-
*cols
– 一系列列、SQL 表示式或整個表實體要返回。 -
sort_by_parameter_order
–對於正在針對多個引數集執行的批次 INSERT,請組織 RETURNING 的結果,使返回的行與傳入的引數集的順序相對應。這僅適用於支援方言的 executemany 執行,並且通常利用 insertmanyvalues 功能。
從版本 2.0.10 開始。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於批次 INSERT 的 RETURNING 行排序的背景(核心級別討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM 批次 INSERT 語句 的使用示例(ORM 級別討論)
另請參閱
UpdateBase.return_defaults()
- 針對單行 INSERT 或 UPDATE,旨在有效地獲取伺服器端預設值和觸發器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程中
class sqlalchemy.sql.expression.Insert
表示一個 INSERT 結構。
Insert
物件是使用 insert()
函式建立的。
成員
values(), returning(), from_select(), inline(), select
類簽名
類 sqlalchemy.sql.expression.Insert
(sqlalchemy.sql.expression.ValuesBase
)
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
繼承自 ValuesBase.values()
方法的 ValuesBase
為 INSERT 語句指定固定的 VALUES 子句,或為 UPDATE 指定 SET 子句。
請注意,Insert
和 Update
構造支援根據傳遞給 Connection.execute()
的引數,在執行時格式化 VALUES 和/或 SET 子句。然而,ValuesBase.values()
方法可以用於將特定一組引數“固定”到語句中。
多次呼叫 ValuesBase.values()
將產生一個新的構造,每個構造的引數列表都會被修改以包含新傳入的引數。在典型情況下,使用單個引數字典,新傳入的鍵將替換前一個構造中的相同鍵。在基於列表的“多值”構造中,每個新的值列表都會被擴充套件到現有的值列表上。
引數:
-
**kwargs
–鍵值對錶示對映到要渲染到 VALUES 或 SET 子句中的值的
Column
的字串鍵:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name")
-
*args
–作為傳遞鍵/值引數的替代方案,可以將字典、元組或字典或元組的列表作為單個位置引數傳遞,以形成語句的 VALUES 或 SET 子句。接受的形式因為是
Insert
還是Update
構造而��所不同。對於
Insert
或Update
構造,可以傳遞一個單獨的字典,其工作方式與 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})
對於任何形式,但更常見於
Insert
構造,也可以接受包含表中每一列的條目的元組:users.insert().values((5, "some name"))
Insert
構造還支援傳遞字典或完整表元組的列表,在伺服器上會呈現較少見的 SQL 語法“多個值” - 這種語法在後端如 SQLite、PostgreSQL、MySQL 等支援,但不一定適用於其他後端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])
上述形式將呈現類似於多個 VALUES 語句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)
必須注意,傳遞多個值並不等同於使用傳統的 executemany()形式。上述語法是一種特殊語法,通常不使用。要針對多行發出 INSERT 語句,正常的方法是將多個值列表傳遞給
Connection.execute()
方法,該方法受到所有資料庫後端的支援,並且通常對大量引數更有效率。另請參見
傳送多個引數 - 介紹了用於 INSERT 和其他語句的多引數集呼叫的傳統 Core 方法。
UPDATE 構造還支援以特定順序渲染 SET 引數。有關此功能,請參閱
Update.ordered_values()
方法。另請參見
Update.ordered_values()
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
繼承自 UpdateBase.returning()
方法的 UpdateBase
為此語句新增一個 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
可以多次呼叫該方法以向返回的表示式列表中新增新條目。
新版本 1.4.0b2 中:可以多次呼叫該方法以向返回的表示式列表中新增新條目。
給定的列表示式集合應派生自 INSERT、UPDATE 或 DELETE 的目標表。雖然 Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,將在語句中呈現 RETURNING 子句或資料庫等效物。對於 INSERT 和 UPDATE,值是新插入/更新的值。對於 DELETE,值是被刪除的行的值。
在執行時,要返回的列的值透過結果集可用,並且可以使用 CursorResult.fetchone()
等進行迭代。對於不原生支援返回值的 DBAPI(即 cx_oracle),SQLAlchemy 將在結果級別近似此行為,以便提供合理數量的行為中立性。
請注意,並非所有資料庫/DBAPI 都支援 RETURNING。對於那些沒有支援的後端,在編譯和/或執行時會引發異常。對於支援它的後端,跨後端的功能差異很大,包括對 executemany() 和其他返回多行語句的限制。請閱讀正在使用的資料庫的文件註釋,以確定 RETURNING 的可用性。
引數:
-
*cols
– 要返回的一系列列、SQL 表示式或整個表實體。 -
sort_by_parameter_order
–對於針對多個引數集執行的批次插入,組織 RETURNING 的結果,使返回的行與傳入的引數集的順序對應。這僅適用於支援方言的 executemany 執行,並且通常利用了 insertmanyvalues 特性。
新版本 2.0.10 中新增。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於批次插入的 RETURNING 行排序的背景(核心級別討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM 批次插入語句 的使用示例(ORM 級別討論)
另請參閱
UpdateBase.return_defaults()
- 一種針對單行插入或更新的伺服器端預設值和觸發器的高效獲取的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程 中
method from_select(names: Sequence[_DMLColumnArgument], select: Selectable, include_defaults: bool = True) → Self
返回一個新的 Insert
構造,該構造表示一個 INSERT...FROM SELECT
語句。
例如:
sel = select(table1.c.a, table1.c.b).where(table1.c.c > 5)
ins = table2.insert().from_select(['a', 'b'], sel)
引數:
-
names
– 字串列名序列或表示目標列的Column
物件。 -
select
– 一個select()
構造,FromClause
或其他可解析為FromClause
的構造,比如 ORMQuery
物件等。此 FROM 子句返回的列的順序應與作為names
引數傳送的列的順序相對應;雖然在傳遞給資料庫之前不會檢查這一點,但如果這些列列表不對應,資料庫通常會引發異常。 -
include_defaults
–如果為 True,則將在 INSERT 和 SELECT 語句中呈現在
Column
物件上指定的非伺服器預設值和 SQL 表示式(如 Column INSERT/UPDATE Defaults 中記錄的)中未在名稱列表中另行指定的值,以便這些值也包含在要插入的資料中。注意
使用 Python 可呼叫函式的 Python 端預設值僅在整個語句中被呼叫一次,而不是每行一次。
method inline() → Self
使此 Insert
構造“內聯”。
當設定時,不會嘗試檢索要在語句中提供的 SQL 生成的預設值;特別是,這允許 SQL 表示式在語句中“內聯”呈現,而無需事先執行它們;對於支援“returning”的後端,這將關閉語句的“隱式返回”功能。
自版本 1.4 起:Insert.inline
引數現已被 Insert.inline()
方法取代。
attribute select: Select[Any] | None = None
用於 INSERT .. FROM SELECT 的 SELECT 語���
class sqlalchemy.sql.expression.Update
表示一個 Update 構造。
使用 update()
函式建立 Update
物件。
成員
returning(), where(), values(), inline(), ordered_values()
類簽名
類 sqlalchemy.sql.expression.Update
(sqlalchemy.sql.expression.DMLWhereBase
, sqlalchemy.sql.expression.ValuesBase
)
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
繼承自 UpdateBase.returning()
方法的 UpdateBase
向此語句新增 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
這種方法可以被多次呼叫,以向要返回的表示式列表中新增新條目。
新版本 1.4.0b2 中新增:這種方法可以被多次呼叫,以向要返回的表示式列表中新增新條目。
給定的列表示式集合應源自 INSERT、UPDATE 或 DELETE 的目標表。雖然 Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,RETURNING 子句或資料庫等效項將在語句中呈現。對於 INSERT 和 UPDATE,值是新插入/更新的值。對於 DELETE,值是已刪除行的值。
在執行時,要返回的列的值透過結果集提供,並且可以使用 CursorResult.fetchone()
等進行迭代。對於原生不支援返回值的 DBAPI(即 cx_oracle 等),SQLAlchemy 將在結果級別近似此行為,以便提供合理數量的行為中性。
請注意,並非所有資料庫/DBAPI 都支援 RETURNING。對於那些不支援的後端,編譯和/或執行時會引發異常。對於支援的後端,跨後端的功能差異很大,包括對 executemany() 和其他返回多行的語句的限制。請閱讀所使用資料庫的文件註釋,以確定 RETURNING 的可用性。
引數:
-
*cols
– 要返回的一系列列、SQL 表示式或整個表實體。 -
sort_by_parameter_order
–對於針對多個引數集執行的批次 INSERT,組織 RETURNING 的結果,使返回的行對應於傳遞的引數集的順序。這僅適用於支援的方言的 executemany 執行,並通常利用 insertmanyvalues 功能。
新版本 2.0.10 中新增。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於批次插入 RETURNING 行排序的背景(核心級討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM 批次插入語句 一起使用的示例(ORM 級討論)
另請參閱
UpdateBase.return_defaults()
- 針對單行 INSERT 或 UPDATE 的高效提取伺服器端預設值和觸發器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程中
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
繼承自 DMLWhereBase
的 DMLWhereBase.where()
方法
返回一個新的結構,其中包含新增到其 WHERE 子句的給定表示式,並透過 AND 連線到現有子句(如果有)。
Update.where()
和 Delete.where()
都支援多表形式,包括特定於資料庫的 UPDATE...FROM
和 DELETE..USING
。 對於不支援多表的後端,使用多表的後端不可知方法是利用相關子查詢。 有關示例,請參見下面的連結教程部分。
另請參閱
相關更新
UPDATE..FROM
多表刪除
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
繼承自 ValuesBase
的 ValuesBase.values()
方法
指定 INSERT 語句的固定 VALUES 子句,或者 UPDATE 的 SET 子句。
請注意,Insert
和 Update
結構支援基於傳遞給 Connection.execute()
的引數對 VALUES 和/或 SET 子句進行每次執行時間格式化。 但是,ValuesBase.values()
方法可用於將特定的一組引數“固定”到語句中。
對 ValuesBase.values()
的多次呼叫將產生一個新的結構,每個結構的引數列表都被修改以包含傳送的新引數。 在單個引數字典的典型情況下,新傳遞的鍵將替換上一個結構中的相同鍵。 在基於列表的“多個值”結構的情況下,每個新值列表都被擴充套件到現有值列表上。
引數:
-
**kwargs
–代表要渲染到 VALUES 或 SET 子句中的值的字串鍵的鍵值對:
users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name")
-
*args
–作為傳遞鍵/值引數的替代方案,可以將字典、元組或字典或元組的列表作為單個位置引數傳遞,以形成語句的 VALUES 或 SET 子句。所接受的形式因為這是否是一個
Insert
或Update
構造而異。對於
Insert
或Update
構造,也可以傳遞單個字典,其工作方式與 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})
也適用於任何形式,但更常見的是對於
Insert
構造,也接受包含表中每列的條目的元組:users.insert().values((5, "some name"))
Insert
構造還支援傳遞字典或完整表元組的列表,在伺服器上,這將呈現較不常見的 SQL 語法“多個值” - 此語法支援後端,例如 SQLite、PostgreSQL、MySQL,但不一定支援其他後端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])
上述形式將呈現類似於多個 VALUES 語句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)
必須注意傳遞多個值並不等同於使用傳統的 executemany() 形式。上述語法是一個特殊語法,通常不使用。要針對多行發出 INSERT 語句,正常方法是將多個值列表傳遞給
Connection.execute()
方法,此方法受到所有資料庫後端的支援,並且對於非常多的引數通常更有效率。另請參閱
傳送多個引數 - 介紹傳統 Core 方法的多引數集呼叫方式,用於 INSERT 和其他語句。
UPDATE 構造還支援按特定順序渲染 SET 引數。有關此功能,請參閱
Update.ordered_values()
方法。另請參閱
Update.ordered_values()
method inline() → Self
將此Update
構造“內聯”。
當設定時,透過default
關鍵字在Column
物件上存在的 SQL 預設值將被‘內聯’編譯到語句中,而不是預先執行。這意味著它們的值不會在從CursorResult.last_updated_params()
返回的字典中可用。
在 1.4 版本中更改:update.inline
引數現在被Update.inline()
方法取代。
method ordered_values(*args: Tuple[_DMLColumnArgument, Any]) → Self
使用顯式引數順序指定此 UPDATE 語句的 VALUES 子句,該順序將在生成的 UPDATE 語句的 SET 子句中保持不變。
例如:
stmt = table.update().ordered_values(
("name", "ed"), ("ident", "foo")
)
另請參閱
引數順序更新 - Update.ordered_values()
方法的完整示例。
在 1.4 版本中更改:Update.ordered_values()
方法取代了update.preserve_parameter_order
引數,該引數將在 SQLAlchemy 2.0 中被移除。
class sqlalchemy.sql.expression.UpdateBase
為INSERT
、UPDATE
和DELETE
語句提供基礎。
成員
entity\_description, exported\_columns, params(), return\_defaults(), returning(), returning\_column\_descriptions, with\_dialect\_options(), with\_hint()
類簽名
類sqlalchemy.sql.expression.UpdateBase
(sqlalchemy.sql.roles.DMLRole
, sqlalchemy.sql.expression.HasCTE
, sqlalchemy.sql.expression.HasCompileState
, sqlalchemy.sql.base.DialectKWArgs
, sqlalchemy.sql.expression.HasPrefixes
, sqlalchemy.sql.expression.Generative
, sqlalchemy.sql.expression.ExecutableReturnsRows
, sqlalchemy.sql.expression.ClauseElement
)
attribute entity_description
返回針對此 DML 構造操作的表和/或實體的啟用外掛描述。
當使用 ORM 時,此屬性通常很有用,因為它返回了一個擴充套件的結構,其中包含有關對映實體的資訊。有關更多背景資訊,請參閱 從 ORM 啟用的 SELECT 和 DML 語句中檢查實體和列。
對於核心語句,此訪問器返回的結構派生自 UpdateBase.table
屬性,並引用正在插入、更新或刪除的Table
:
>>> stmt = insert(user_table)
>>> stmt.entity_description
{
"name": "user_table",
"table": Table("user_table", ...)
}
新功能,版本 1.4.33。
另請參閱
UpdateBase.returning_column_descriptions
Select.column_descriptions
- select()
構造的實體資訊
從 ORM 啟用的 SELECT 和 DML 語句中檢查實體和列 - ORM 背景
attribute exported_columns
返回該語句的 RETURNING 列作為列集合。
新功能,版本 1.4。
method params(*arg: Any, **kw: Any) → NoReturn
設定語句的引數。
此方法在基類上引發 NotImplementedError
,並由ValuesBase
覆蓋以提供 UPDATE 和 INSERT 的 SET/VALUES 子句。
method return_defaults(*cols: _DMLColumnArgument, supplemental_cols: Iterable[_DMLColumnArgument] | None = None, sort_by_parameter_order: bool = False) → Self
利用 RETURNING 子句以獲取伺服器端表示式和預設值,僅支援後端。
深度鍊金術
UpdateBase.return_defaults()
方法被 ORM 用於其內部工作中,用於獲取新生成的主鍵和伺服器預設值,特別是為了提供Mapper.eager_defaults
ORM 特性的底層實現,以及允許在批次 ORM 插入中支援 RETURNING。其行為相當特殊,實際上不適合一般使用。終端使用者應堅持使用UpdateBase.returning()
來為他們的 INSERT、UPDATE 和 DELETE 語句新增 RETURNING 子句。
通常,執行單行 INSERT 語句時,會自動填充CursorResult.inserted_primary_key
屬性,該屬性儲存了剛剛插入的行的主鍵,以Row
物件的形式,列名作為命名元組鍵(並且Row._mapping
檢視也完全填充)。使用的方言選擇用於填充這些資料的策略;如果是使用伺服器端預設值和/或 SQL 表示式生成的,則通常使用特定於方言的方法(如cursor.lastrowid
或RETURNING
)來獲取新的主鍵值。
然而,在執行語句之前透過呼叫UpdateBase.return_defaults()
修改語句時,只有支援 RETURNING 並且將Table.implicit_returning
引數維持在其預設值True
的後端以及維護Table
物件的其他行為才會發生。在這些情況下,當從語句的執行返回CursorResult
時,不僅CursorResult.inserted_primary_key
將像往常一樣被填充,CursorResult.returned_defaults
屬性還將被填充為一個名為Row
的命名元組,代表該單行的完整伺服器生成值範圍,包括任何指定Column.server_default
或使用 SQL 表示式的Column.default
的列的值。
當使用 insertmanyvalues 呼叫多行的 INSERT 語句時,UpdateBase.return_defaults()
修飾符將會影響CursorResult.inserted_primary_key_rows
和CursorResult.returned_defaults_rows
屬性被完全填充為代表每行新插入的主鍵值以及新插入的伺服器生成值的Row
物件列表。CursorResult.inserted_primary_key
和CursorResult.returned_defaults
屬性也將繼續被填充為這兩個集合的第一行。
如果後端不支援 RETURNING 或者正在使用的 Table
已經禁用了 Table.implicit_returning
,那麼就不會新增 RETURNING 子句,也不會獲取任何額外的資料,但是 INSERT、UPDATE 或 DELETE 語句會正常執行。
例如:
stmt = table.insert().values(data='newdata').return_defaults()
result = connection.execute(stmt)
server_created_at = result.returned_defaults['created_at']
當用於 UPDATE 語句時,UpdateBase.return_defaults()
會查詢包含 Column.onupdate
或 Column.server_onupdate
引數的列,當構造預設情況下將包含在 RETURNING 子句中的列時(如果未明確指定列)。當用於 DELETE 語句時,預設情況下不會包含任何列在 RETURNING 中,而是必須明確指定,因為在 DELETE 語句執行時通常不會更改值的列。
從版本 2.0 開始:UpdateBase.return_defaults()
也支援 DELETE 語句,並且已從 ValuesBase
移動到 UpdateBase
。
UpdateBase.return_defaults()
方法與 UpdateBase.returning()
方法互斥,在同一條語句上同時使用兩者會在 SQL 編譯過程中引發錯誤。因此,INSERT、UPDATE 或 DELETE 語句的 RETURNING 子句一次只能由其中一個方法控制。
UpdateBase.return_defaults()
方法與 UpdateBase.returning()
在以下方面不同:
-
UpdateBase.return_defaults()
方法導致CursorResult.returned_defaults
集合被填充為 RETURNING 結果的第一行。當使用UpdateBase.returning()
時,此屬性不會被填充。 -
UpdateBase.return_defaults()
與用於獲取自動生成的主鍵值並將其填充到CursorResult.inserted_primary_key
屬性的現有邏輯相容。相比之下,使用UpdateBase.returning()
將導致CursorResult.inserted_primary_key
屬性保持未填充狀態。 -
UpdateBase.return_defaults()
可以針對任何後端呼叫。不支援 RETURNING 的後端將跳過該功能的使用,而不是引發異常,除非傳遞了supplemental_cols
。對於不支援 RETURNING 或目標Table
設定Table.implicit_returning
為False
的後端,CursorResult.returned_defaults
的返回值將為None
。 -
使用
executemany()
呼叫的 INSERT 語句在後端資料庫驅動程式支援 insertmanyvalues 功能的情況下得到支援,這個功能現在大多數包含在 SQLAlchemy 中的後端都支援。當使用executemany
時,CursorResult.returned_defaults_rows
和CursorResult.inserted_primary_key_rows
訪問器將返回插入的預設值和主鍵。1.4 版本中新增:新增了
CursorResult.returned_defaults_rows
和CursorResult.inserted_primary_key_rows
訪問器。在 2.0 版本中,用於獲取和填充這些屬性的底層實現被泛化以支援大多數後端,而在 1.4 版本中,它們僅由psycopg2
驅動程式支援。
引數:
-
cols
– 可選的列鍵名列表或Column
,作為過濾器用於將要獲取的列。 -
supplemental_cols
–可選的 RETURNING 表示式列表,與
UpdateBase.returning()
方法傳遞的形式相同。當存在時,額外的列將包含在 RETURNING 子句中,並且在返回時,CursorResult
物件將被“倒帶”,以便像CursorResult.all()
這樣的方法將以大部分方式返回新行,就好像語句直接使用了UpdateBase.returning()
。但是,與直接使用UpdateBase.returning()
時不同,列的順序是未定義的,因此只能使用名稱或Row._mapping
鍵來定位它們;它們不能可靠地以位置為目標。2.0 版本中新增。
-
sort_by_parameter_order
–對於正在針對多個引數集執行的批次插入,組織返回的 RETURNING 結果,使返回的行與傳遞的引數集的順序相對應。這僅適用於支援方言的 executemany 執行,並且通常利用 insertmanyvalues 功能。
2.0.10 版本中新增。
另請參閱
將返回的行與引數集相關聯 - 關於批次插入的返回行排序的背景知識
另請參閱
UpdateBase.returning()
CursorResult.returned_defaults
CursorResult.returned_defaults_rows
CursorResult.inserted_primary_key
CursorResult.inserted_primary_key_rows
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
向該語句新增一個 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
該方法可以多次呼叫以向要返回的表示式列表新增新條目。
從版本 1.4.0b2 開始新新增:該方法可以多次呼叫以向要返回的表示式列表新增新條目。
給定的列表示式集合應該來源於作為 INSERT、UPDATE 或 DELETE 目標的表。雖然 Column
物件很典型,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,RETURNING 子句或資料庫等效項將在語句內呈現。對於 INSERT 和 UPDATE,這些值是新插入/更新的值。對於 DELETE,這些值是被刪除的行的值。
在執行時,要返回的列的值透過結果集可用,並且可以使用 CursorResult.fetchone()
等進行迭代。對於不本地支援返回值的 DBAPI(即 cx_oracle),SQLAlchemy 將在結果級別上近似此行為,以便提供合理數量的行為中立性。
請注意,並非所有資料庫/DBAPI 都支援 RETURNING。對於沒有支援的後端,在編譯和/或執行時會引發異常。對於支援的後端,跨後端的功能差異很大,包括對 executemany() 和其他返回多行的語句的限制。請閱讀正在使用的資料庫的文件說明,以確定 RETURNING 的可用性。
引數:
-
*cols
– 一系列列、SQL 表示式或整個表實體,要返回。 -
sort_by_parameter_order
–對於正在執行針對多個引數集的批次 INSERT,組織 RETURNING 的結果,以便返回的行與傳入的引數集的順序對應。這僅適用於對支援的方言執行的 executemany 操作,通常利用 insertmanyvalues 功能。
從版本 2.0.10 開始新新增。
另請參閱
將 RETURNING 行相關聯到引數集 - 對批次 INSERT 的 RETURNING 行排序的背景資訊(核心級別討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM 大批次 INSERT 語句 使用示例(ORM 級別討論)
另請參閱
UpdateBase.return_defaults()
- 針對單行 INSERT 或 UPDATE,針對高效獲取伺服器端預設值和觸發器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程 中
attribute returning_column_descriptions
返回此 DML 構造體返回的列的 外掛啟用 描述,換句話說,作為 UpdateBase.returning()
的一部分建立的表示式。
當使用 ORM 時,此屬性通常很有用,因為返回的擴充套件結構包含有關對映實體的資訊。該部分 從 ORM 啟用的 SELECT 和 DML 語句中檢查實體和列 包含更多背景資訊。
對於核心語句,此訪問器返回的結構源自與 UpdateBase.exported_columns
訪問器返回的相同物件:
>>> stmt = insert(user_table).returning(user_table.c.id, user_table.c.name)
>>> stmt.entity_description
[
{
"name": "id",
"type": Integer,
"expr": Column("id", Integer(), table=<user>, ...)
},
{
"name": "name",
"type": String(),
"expr": Column("name", String(), table=<user>, ...)
},
]
版本 1.4.33 中的新功能。
另請參閱
UpdateBase.entity_description
Select.column_descriptions
- 用於 select()
構造的實體資訊
從 ORM 啟用的 SELECT 和 DML 語句中檢查實體和列 - ORM 背景
method with_dialect_options(**opt: Any) → Self
將方言選項新增到此 INSERT/UPDATE/DELETE 物件中。
例如:
upd = table.update().dialect_options(mysql_limit=10)
method with_hint(text: str, selectable: _DMLTableArgument | None = None, dialect_name: str = '*') → Self
將單個表的表提示新增到此 INSERT/UPDATE/DELETE 語句中。
注意
UpdateBase.with_hint()
目前僅適用於 Microsoft SQL Server。對於 MySQL INSERT/UPDATE/DELETE 提示,請使用 UpdateBase.prefix_with()
。
提示文字在使用的資料庫後端的適當位置呈現,與此語句的主題 Table
相對應,或者可選地,相對於傳遞為 selectable
引數的給定 Table
。
dialect_name
選項將限制特定後端的特定提示的呈現。例如,要新增一個僅在 SQL Server 中生效的提示:
mytable.insert().with_hint("WITH (PAGLOCK)", dialect_name="mssql")
引數:
-
text
– 提示的文字。 -
selectable
– 可選的Table
,指定在 UPDATE 或 DELETE 中作為提示主題的 FROM 子句的元素 - 僅適用於某些後端。 -
dialect_name
– 預設為*
,如果指定為特定方言的名稱,將僅在使用該方言時應用這些提示。
class sqlalchemy.sql.expression.ValuesBase
為 INSERT 和 UPDATE 構造提供對ValuesBase.values()
的支援。
成員
select, values()
類簽名
類sqlalchemy.sql.expression.ValuesBase
(sqlalchemy.sql.expression.UpdateBase
)
attribute select: Select[Any] | None = None
用於 INSERT .. FROM SELECT 的 SELECT 語句
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
為 INSERT 語句指定一個固定的 VALUES 子句,或者為 UPDATE 指定 SET 子句。
請注意,Insert
和Update
構造支援基於傳遞給Connection.execute()
的引數對 VALUES 和/或 SET 子句進行每次執行時的格式化。但是,ValuesBase.values()
方法可用於將特定一組引數“固定”到語句中。
對ValuesBase.values()
的多次呼叫將產生一個新的構造,每個構造的引數列表都會修改以包含傳送的新引數。在單個引數字典的典型情況下,新傳遞的鍵將替換先前構造中的相同鍵。在基於列表的“多個值”構造的情況下,每個新值列表都會擴充套件到現有值列表上。
引數:
-
**kwargs
–表示要對映到 VALUES 或 SET 子句中的值的
Column
的字串鍵值對:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name")
-
*args
–作為傳遞鍵/值引數的替代方案,可以將字典、元組或字典列表或元組作為單個位置引數傳遞,以形成語句的 VALUES 或 SET 子句。接受的形式因是
Insert
還是Update
構造而異。對於
Insert
或Update
構造,可以傳遞一個單獨的字典,其工作方式與 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})
對於任何形式,但更典型的是
Insert
構造,也可以接受包含表中每一列條目的元組:users.insert().values((5, "some name"))
Insert
構造還支援傳遞一個字典列表或完整表元組,伺服器上將呈現較不常見的 SQL 語法“多個值” - 此語法在後端(如 SQLite、PostgreSQL、MySQL)上受支援,但不一定適用於其他後端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])
上述形式將呈現類似於多個 VALUES 語句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)
需要注意的是傳遞多個值並不等同於使用傳統的 executemany()形式。上述語法是一種特殊的語法,通常不常用。要對多行發出 INSERT 語句,正常方法是將多個值列表傳遞給
Connection.execute()
方法,這種方法受到所有資料庫後端的支援,並且對於非常大量的引數通常更有效率。另請參閱
傳送多個引數 - 介紹了用於 INSERT 和其他語句的傳統 Core 方法的多引數集呼叫。
UPDATE 構造還支援按特定順序呈現 SET 引數。有關此功能,請參考
Update.ordered_values()
方法。另請參閱
Update.ordered_values()
DML 基礎構造
頂層“INSERT”、“UPDATE”、“DELETE”建構函式。
物件名稱 | 描述 |
---|---|
delete(table) | 構造Delete 物件。 |
insert(table) | 構造一個Insert 物件。 |
更新(table) | 構造一個Update 物件。 |
function sqlalchemy.sql.expression.delete(table: _DMLTableArgument) → Delete
構造Delete
物件。
例如:
from sqlalchemy import delete
stmt = (
delete(user_table).
where(user_table.c.id == 5)
)
類似功能也可透過TableClause.delete()
方法在Table
上獲得。
引數:
table – 要從中刪除行的表。
另請參閱
使用 UPDATE 和 DELETE 語句 - 在 SQLAlchemy 統一教程中
function sqlalchemy.sql.expression.insert(table: _DMLTableArgument) → Insert
構造一個Insert
物件。
例如:
from sqlalchemy import insert
stmt = (
insert(user_table).
values(name='username', fullname='Full Username')
)
類似功能也可透過TableClause.insert()
方法在Table
上獲得。
另請參閱
使用 INSERT 語句 - 在 SQLAlchemy 統一教程中
引數:
-
table
–TableClause
,即插入主題。 -
values
– 要插入的值集合;請參閱Insert.values()
以獲取此處允許的格式描述。可以完全省略;Insert
構造還將根據傳遞給Connection.execute()
的引數,在執行時動態渲染 VALUES 子句。 -
inline
– 如果為 True,則不會嘗試檢索生成的 SQL 預設值,以便在語句中提供;特別地,這允許 SQL 表示式在語句中“內聯”渲染,而無需事先執行它們;對於支援“返回”的後端,這會關閉語句的“隱式返回”功能。
如果同時存在insert.values
和編譯時繫結引數,則編譯時繫結引數將覆蓋在insert.values
中指定的資訊,按鍵分別覆蓋。
Insert.values
中的鍵可以是 Column
物件或它們的字串識別符號。 每個鍵可能引用以下之一:
-
一個字面資料值(即字串、數字等);
-
一個 Column 物件;
-
一個 SELECT 語句。
如果指定了一個 SELECT
語句,該語句引用了此 INSERT
語句的表,那麼該語句將與 INSERT
語句相關聯。
另請參閱
使用 INSERT 語句 - 在 SQLAlchemy 統一教程 中
function sqlalchemy.sql.expression.update(table: _DMLTableArgument) → Update
構造一個 Update
物件。
例如:
from sqlalchemy import update
stmt = (
update(user_table).
where(user_table.c.id == 5).
values(name='user #5')
)
類似功能也可透過 TableClause.update()
方法在 Table
上獲得。
引數:
table – 代表要更新的資料庫表的 Table
物件。
另請參閱
使用 UPDATE 和 DELETE 語句 - 在 SQLAlchemy 統一教程 中
DML 類文件建構函式
DML Foundational Constructors 中列出的建構函式的類文件。
物件名稱 | 描述 |
---|---|
Delete | 代表一個 DELETE 結構。 |
Insert | 代表一個 INSERT 結構。 |
Update | 代表一個 Update 結構。 |
UpdateBase | 形成 INSERT 、UPDATE 和 DELETE 語句的基礎。 |
ValuesBase | 為 INSERT 和 UPDATE 結構提供 ValuesBase.values() 的支援。 |
class sqlalchemy.sql.expression.Delete
代表一個 DELETE 結構。
Delete
物件是使用 delete()
函式建立的。
成員
where(), returning()
類簽名
類sqlalchemy.sql.expression.Delete
(sqlalchemy.sql.expression.DMLWhereBase
,sqlalchemy.sql.expression.UpdateBase
)
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
繼承自 DMLWhereBase
的 DMLWhereBase.where()
方法
返回一個新的構造,其中給定的表示式被新增到其 WHERE 子句中,並透過 AND 連線到現有子句(如果有)。
Update.where()
和 Delete.where()
都支援多表形式,包括特定於資料庫的UPDATE...FROM
以及DELETE..USING
。對於不支援多表的後端,使用多表的跨後端方法是利用相關子查詢。請參閱下面連結的教程部分以獲取示例。
另請參見
相關更新
UPDATE..FROM
多表刪除
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
繼承自 UpdateBase.returning()
方法的 UpdateBase
為該語句新增一個 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
可以多次呼叫該方法以向要返回的表示式列表中新增新條目。
從版本 1.4.0b2 開始:可以多次呼叫該方法以向要返回的表示式列表中新增新條目。
給定的列表示式集合應源自 INSERT、UPDATE 或 DELETE 的目標表。雖然Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,將在語句中呈現 RETURNING 子句或資料庫等效。對於 INSERT 和 UPDATE,值是新插入/更新的值。對於 DELETE,值是被刪除的行的值。
在執行時,要返回的列的值透過結果集提供,並可以使用CursorResult.fetchone()
等進行迭代。對於不原生支援返回值的 DBAPI(即 cx_oracle),SQLAlchemy 將在結果級別近似此行為,以便提供合理數量的行為中立性。
請注意,並非所有資料庫/DBAPI 都支援 RETURNING。對於那些不支援的後端,在編譯和/或執行時會引發異常。對於支援它的後端,跨後端的功能差異很大,包括對 executemany()和返回多行的其他語句的限制。請閱讀所使用資料庫的文件註釋,以確定 RETURNING 的可用性。
引數:
-
*cols
– 要返回的一系列列、SQL 表示式或整個表實體。 -
sort_by_parameter_order
–對於針對多個引數集執行的批次插入,組織 RETURNING 的結果,使返回的行與傳入的引數集的順序對應。這僅適用於支援方言的 executemany 執行,並通常利用 insertmanyvalues 功能。
版本 2.0.10 中的新功能。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於批次插入 RETURNING 行排序的背景(核心級別討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM 批次 INSERT 語句 的使用示例(ORM 級別討論)
另請參閱
UpdateBase.return_defaults()
- 一種針對單行 INSERT 或 UPDATE 的有效獲取伺服器端預設值和觸發器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程 中
class sqlalchemy.sql.expression.Insert
表示一個 INSERT 構造。
Insert
物件是使用 insert()
函式建立的。
成員
values(), returning(), from_select(), inline(), select
類簽名
類 sqlalchemy.sql.expression.Insert
(sqlalchemy.sql.expression.ValuesBase
)
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
繼承自 ValuesBase.values()
方法的 ValuesBase
為 INSERT 語句指定固定的 VALUES 子句,或為 UPDATE 指定 SET 子句。
請注意,Insert
和Update
構造支援基於傳遞給Connection.execute()
的引數對 VALUES 和/或 SET 子句進行執行時格式化。但是,ValuesBase.values()
方法可用於將特定一組引數“固定”到語句中。
多次呼叫ValuesBase.values()
將生成一個新構造,每個構造的引數列表都會修改以包含傳送的新引數。在典型情況下,單個引數字典中的新傳遞鍵將替換先前構造中的相同鍵。在基於列表的“多個值”構造的情況下,每個新值列表都會擴充套件到現有值列表上。
引數:
-
**kwargs
–鍵值對錶示
Column
的字串鍵對映到要呈現到 VALUES 或 SET 子句中的值:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name")
-
*args
–作為傳遞鍵/值引數的替代方案,可以將字典、元組或字典或元組的列表作為單個位置引數傳遞,以形成語句的 VALUES 或 SET 子句。接受的形式因此是一個
Insert
還是一個Update
構造而異。對於
Insert
或Update
構造,可以傳遞一個字典,其工作方式與 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})
對於任何形式,但更典型地用於
Insert
構造,也接受包含表中每列條目的元組:users.insert().values((5, "some name"))
Insert
構造還支援傳遞字典或完整表元組的列表,這在伺服器上將呈現較少見的 SQL 語法“多個值” - 此語法在後端(如 SQLite、PostgreSQL、MySQL)上受支援,但不一定在其他後端上受支援:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])
上述形式將呈現類似於多個 VALUES 語句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)
必須注意傳遞多個值並不等同於使用傳統的 executemany()形式。上述語法是一種特殊的語法,通常不常用。要針對多行發出 INSERT 語句,正常方法是將多個值列表傳遞給
Connection.execute()
方法,該方法受到所有資料庫後端支援,並且對於非常大量的引數通常更有效率。另請參閱
傳送多個引數 - 介紹傳統核心方法的多引數集呼叫,用於 INSERT 和其他語句。
UPDATE 結構還支援按特定順序呈現 SET 引數。有關此功能,請參考
Update.ordered_values()
方法。另請參閱
Update.ordered_values()
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
繼承自 UpdateBase.returning()
方法的 UpdateBase
在此語句中新增一個 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
可以多次呼叫該方法以向要返回的表示式列表新增新條目。
從版本 1.4.0b2 中新增:可以多次呼叫該方法以向要返回的表示式列表新增新條目。
給定的列表示式集合應源自 INSERT、UPDATE 或 DELETE 的目標表。雖然Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,將在語句中呈現一個 RETURNING 子句,或者資料庫等效項。對於 INSERT 和 UPDATE,這些值是新插入/更新的值。對於 DELETE,這些值是被刪除的行的值。
在執行時,要返回的列的值透過結果集提供,並可以使用CursorResult.fetchone()
等進行迭代。對於不本地支援返回值的 DBAPI(即 cx_oracle),SQLAlchemy 將在結果級別近似此行為,以便提供合理數量的行為中立性。
請注意,並非所有資料庫/DBAPI 都支援 RETURNING。對於那些不支援的後端,在編譯和/或執行時會引發異常。對於那些支援它的後端,跨後端的功能差異很大,包括對 executemany()和其他返回多行的語句的限制。請閱讀正在使用的資料庫的文件說明,以確定 RETURNING 的可用性。
引數:
-
*cols
– 一系列列、SQL 表示式或整個表實體要返回。 -
sort_by_parameter_order
–對於正在針對多個引數集執行的批次 INSERT,組織 RETURNING 的結果,使返回的行與傳入的引數集的順序對應。這僅適用於支援方言的 executemany 執行,並通常利用 insertmanyvalues 功能。
2.0.10 版中的新功能。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於批次 INSERT 的 RETURNING 行排序的背景(核心級別討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM 批次 INSERT 語句一起使用的示例(ORM 級別討論)
另請參閱
UpdateBase.return_defaults()
- 一種針對高效獲取伺服器端預設值和觸發器的單行 INSERT 或 UPDATE 的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程中
method from_select(names: Sequence[_DMLColumnArgument], select: Selectable, include_defaults: bool = True) → Self
返回一個新的Insert
構造,表示一個INSERT...FROM SELECT
語句。
例如:
sel = select(table1.c.a, table1.c.b).where(table1.c.c > 5)
ins = table2.insert().from_select(['a', 'b'], sel)
引數:
-
names
– 一系列字串列名或Column
物件,表示目標列。 -
select
– 一個select()
構造,FromClause
或其他解析為FromClause
的構造,例如 ORMQuery
物件等。從此 FROM 子句返回的列的順序應與作為names
引數傳送的列的順序相對應;雖然在傳遞給資料庫之前不會檢查這一點,但如果這些列列表不對應,資料庫通常會引發異常。 -
include_defaults
–如果為 True,則將渲染到 INSERT 和 SELECT 語句中的非伺服器預設值和在
Column
物件上指定的 SQL 表示式(如 Column INSERT/UPDATE Defaults 中所記錄)未在名稱列表中另行指定,以便這些值也包含在要插入的資料中。注意
使用 Python 可呼叫函式的 Python 端預設值將僅在整個語句中被呼叫 一次,而不是每行一次。
method inline() → Self
將此 Insert
構造“內聯”。
當設定時,將不會嘗試檢索在語句中提供的 SQL 生成的預設值;特別是,這允許 SQL 表示式在語句中“內聯”渲染,無需事先對它們進行預執行;對於支援“returning”的後端,這將關閉語句的“隱式返回”功能。
在版本 1.4 中進行了更改:Insert.inline
引數現已被 Insert.inline()
方法取代。
attribute select: Select[Any] | None = None
INSERT .. FROM SELECT 的 SELECT 語句
class sqlalchemy.sql.expression.Update
表示一個 Update 構造。
使用 update()
函式建立 Update
物件。
成員
returning(), where(), values(), inline(), ordered_values()
類簽名
類 sqlalchemy.sql.expression.Update
(sqlalchemy.sql.expression.DMLWhereBase
,sqlalchemy.sql.expression.ValuesBase
)
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
繼承自 UpdateBase.returning()
方法的 UpdateBase
向該語句新增一個 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
此方法可以多次呼叫以向要返回的表示式列表新增新條目。
新版本 1.4.0b2 中:此方法可以多次呼叫以向要返回的表示式列表新增新條目。
給定的列表示式集合應源自是 INSERT、UPDATE 或 DELETE 目標的表。雖然 Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
編譯時,RETURNING 子句或資料庫等效項將包含在語句中。對於 INSERT 和 UPDATE,這些值是新插入/更新的值。對於 DELETE,這些值是被刪除行的值。
在執行時,要返回的列的值透過結果集提供,並可以使用 CursorResult.fetchone()
和類似方法進行迭代。對於不原生支援返回值的 DBAPI(即 cx_oracle 等),SQLAlchemy 將在結果級別近似此行為,以提供合理數量的行為中立性。
請注意,並非所有資料庫/DBAPI 都支援 RETURNING。對於那些沒有支援的後端,在編譯和/或執行時會引發異常。對於支援的後端,跨後端的功能差異很大,包括對 executemany() 和其他返回多行的語句的限制。請閱讀使用中的資料庫的文件註釋,以確定 RETURNING 的可用性。
引數:
-
*cols
– 一系列要返回的列、SQL 表示式或整個表實體。 -
sort_by_parameter_order
–對於正在執行多個引數集的批次 INSERT,組織 RETURNING 的結果,使返回的行與傳入的引數集的順序對應。這僅適用於支援的方言的 executemany 執行,並且通常利用 insertmanyvalues 功能。
在 2.0.10 版本中新增。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於批次插入 RETURNING 行排序的背景(核心層討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 在 ORM 批次 INSERT 語句 中的使用示例(ORM 層討論)
另請參閱
UpdateBase.return_defaults()
- 針對高效獲取單行 INSERT 或 UPDATE 的伺服器端預設值和觸發器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程 中
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
從 DMLWhereBase.where()
方法的 DMLWhereBase
繼承
返回一個新的構造,其中包含要新增到其 WHERE 子句中的給定表示式,如果有的話,透過 AND 連線到現有子句。
Update.where()
和Delete.where()
都支援多表形式,包括資料庫特定的UPDATE...FROM
以及DELETE..USING
。 對於不支援多表的後端,使用多表的後端不可知方法是利用相關子查詢。 有關示例,請參閱下面連結的教程部分。
亦見
相關更新
UPDATE..FROM
多表刪除
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
繼承自 ValuesBase.values()
方法的 ValuesBase
為 INSERT 語句指定一個固定的 VALUES 子句,或者為 UPDATE 指定 SET 子句。
請注意,Insert
和Update
構造支援基於傳遞給Connection.execute()
的引數對 VALUES 和/或 SET 子句進行每次執行時間格式化。 但是,ValuesBase.values()
方法可用於將特定引數集固定到語句中。
多次呼叫ValuesBase.values()
將產生一個新的構造,每個構造都將引數列表修改為包含新傳送的引數。 在單個引數字典的典型情況下,新傳遞的鍵將替換先前構造中的相同鍵。 在基於列表的“多值”構造的情況下,每個新值列表都被擴充套件到現有值列表上。
引數:
-
**kwargs
–表示將對映到要渲染到 VALUES 或 SET 子句中的值的
Column
的字串鍵值對:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name")
-
*args
–作為傳遞鍵/值引數的替代方案,可以將字典、元組或字典或元組的列表作為單個位置引數傳遞,以形成語句的 VALUES 或 SET 子句。被接受的形式因為是
Insert
還是Update
構造而異。對於
Insert
或Update
構造,可以傳遞單個字典,其效果與 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})
對於任何形式,但更常見的是
Insert
構造,也可以接受包含表中每一列條目的元組:users.insert().values((5, "some name"))
Insert
構造還支援傳遞字典或完整表元組的列表,這將在伺服器上呈現較少使用的 SQL 語法 "多個值" - 此語法受到後端(如 SQLite、PostgreSQL、MySQL)的支援,但不一定適用於其他後端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])
上述形式將呈現類似於多個 VALUES 語句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)
必須注意 傳遞多個值並不等同於使用傳統的 executemany() 形式。上述語法是一種 特殊 的語法,通常不使用。要針對多行發出 INSERT 語句,正常的方法是將多個值列表傳遞給
Connection.execute()
方法,這受到所有資料庫後端的支援,並且對於非常大量的引數通常更有效率。另請參閱
傳送多個引數 - 介紹了傳統的 Core 方法,用於 INSERT 和其他語句的多引數集呼叫。
UPDATE 構造還支援按特定順序渲染 SET 引數。有關此功能,請參閱
Update.ordered_values()
方法。另請參閱
Update.ordered_values()
method inline() → Self
使此 Update
構造 "內聯"。
當設定時,透過default
關鍵字在Column
物件上存在的 SQL 預設值將被編譯為語句中的‘inline’並且不會預先執行。這意味著它們的值不會出現在CursorResult.last_updated_params()
返回的字典中。
在 1.4 版本中更改:update.inline
引數現已由Update.inline()
方法取代。
method ordered_values(*args: Tuple[_DMLColumnArgument, Any]) → Self
使用顯式引數排序指定此 UPDATE 語句的 VALUES 子句,在結果 UPDATE 語句的 SET 子句中將保持該順序。
例如:
stmt = table.update().ordered_values(
("name", "ed"), ("ident", "foo")
)
另請參閱
引數有序更新 - Update.ordered_values()
方法的完整示例。
在 1.4 版本中更改:Update.ordered_values()
方法取代了update.preserve_parameter_order
引數,該引數將在 SQLAlchemy 2.0 中移除。
class sqlalchemy.sql.expression.UpdateBase
為INSERT
、UPDATE
和DELETE
語句提供基礎。
成員
entity_description, exported_columns, params(), return_defaults(), returning(), returning_column_descriptions, with_dialect_options(), with_hint()
類簽名
類sqlalchemy.sql.expression.UpdateBase
(sqlalchemy.sql.roles.DMLRole
, sqlalchemy.sql.expression.HasCTE
, sqlalchemy.sql.expression.HasCompileState
, sqlalchemy.sql.base.DialectKWArgs
, sqlalchemy.sql.expression.HasPrefixes
, sqlalchemy.sql.expression.Generative
, sqlalchemy.sql.expression.ExecutableReturnsRows
, sqlalchemy.sql.expression.ClauseElement
)
attribute entity_description
返回此 DML 結構操作的表和/或實體的外掛啟用描述。
當使用 ORM 時,此屬性通常很有用,因為它返回一個擴充套件結構,其中包含有關對映實體的資訊。從 ORM 啟用的 SELECT 和 DML 語句中檢查實體和列部分提供了更多背景資訊。
對於 Core 語句,此訪問器返回的結構源自UpdateBase.table
屬性,並引用正在插入、更新或刪除的Table
:
>>> stmt = insert(user_table)
>>> stmt.entity_description
{
"name": "user_table",
"table": Table("user_table", ...)
}
版本 1.4.33 中的新功能。
請參閱
UpdateBase.returning_column_descriptions
Select.column_descriptions
- select()
構造的實體資訊
從 ORM 啟用的 SELECT 和 DML 語句中檢查實體和列 - ORM 背景
attribute exported_columns
將 RETURNING 列作為此語句的列集合返回。
版本 1.4 中的新功能。
method params(*arg: Any, **kw: Any) → NoReturn
設定語句的引數。
此方法在基類上引發NotImplementedError
,並由ValuesBase
覆蓋,以提供 UPDATE 和 INSERT 的 SET/VALUES 子句。
method return_defaults(*cols: _DMLColumnArgument, supplemental_cols: Iterable[_DMLColumnArgument] | None = None, sort_by_parameter_order: bool = False) → Self
僅支援後端,使用 RETURNING 子句以獲取伺服器端表示式和預設值。
深度鍊金術
UpdateBase.return_defaults()
方法被 ORM 用於其內部工作中,以獲取新生成的主鍵和伺服器預設值,特別是為了提供Mapper.eager_defaults
ORM 特性的基礎實現,以及允許批次 ORM 插入時的 RETURNING 支援。它的行為相當特殊,實際上並不打算用於一般用途。終端使用者應該堅持使用UpdateBase.returning()
來新增 RETURNING 子句到他們的 INSERT、UPDATE 和 DELETE 語句中。
通常情況下,單行 INSERT 語句在執行時會自動填充CursorResult.inserted_primary_key
屬性,該屬性以Row
物件的形式儲存剛剛插入的行的主鍵,其中列名作為命名元組鍵(並且Row._mapping
檢視也被完全填充)。正在使用的方言選擇用於填充這些資料的策略;如果它是使用伺服器端預設值和/或 SQL 表示式生成的,則通常會使用方言特定的方法,如cursor.lastrowid
或RETURNING
來獲取新的主鍵值。
然而,當在執行語句之前透過呼叫UpdateBase.return_defaults()
對語句進行修改時,僅對支援 RETURNING 的後端以及將Table.implicit_returning
引數保持其預設值True
的Table
物件發生附加行為。在這些情況下,當從語句的執行返回CursorResult
時,不僅CursorResult.inserted_primary_key
像往常一樣被填充,CursorResult.returned_defaults
屬性還將被填充為一個命名為Row
的元組,代表該單行的所有伺服器生成的值的完整範圍,包括任何指定Column.server_default
或使用 SQL 表示式的Column.default
的列的值。
當使用 insertmanyvalues 來呼叫具有多行的 INSERT 語句時,UpdateBase.return_defaults()
修飾符將導致CursorResult.inserted_primary_key_rows
和CursorResult.returned_defaults_rows
屬性完全填充,其中包含代表新插入的主鍵值以及每行插入的新生成的伺服器值的Row
物件的列表。CursorResult.inserted_primary_key
和CursorResult.returned_defaults
屬性也將繼續填充這兩個集合的第一行。
如果後端不支援 RETURNING,或者正在使用的 Table
禁用了 Table.implicit_returning
,則不會新增 RETURNING 子句,也不會獲取額外資料,但 INSERT、UPDATE 或 DELETE 語句會正常執行。
例如:
stmt = table.insert().values(data='newdata').return_defaults()
result = connection.execute(stmt)
server_created_at = result.returned_defaults['created_at']
當針對 UPDATE 語句使用 UpdateBase.return_defaults()
時,會查詢包含 Column.onupdate
或 Column.server_onupdate
引數的列,用於構建預設情況下將包含在 RETURNING 子句中的列(如果未顯式指定列)。當針對 DELETE 語句使用時,預設情況下不包含任何列在 RETURNING 中,而必須顯式指定,因為在 DELETE 語句進行時通常不會更改值的列。
新功能在版本 2.0 中:UpdateBase.return_defaults()
現在也支援 DELETE 語句,並且已經從 ValuesBase
移動到 UpdateBase
。
UpdateBase.return_defaults()
方法與 UpdateBase.returning()
方法是互斥的,如果同時在一個語句上使用了兩者,將在 SQL 編譯過程中引發錯誤。因此,INSERT、UPDATE 或 DELETE 語句的 RETURNING 子句只由其中一個方法控制。
UpdateBase.return_defaults()
方法與 UpdateBase.returning()
的不同之處在於:
-
UpdateBase.return_defaults()
方法導致CursorResult.returned_defaults
集合被填充為 RETURNING 結果的第一行。當使用UpdateBase.returning()
時,此屬性不會被填充。 -
UpdateBase.return_defaults()
與用於獲取自動生成的主鍵值並將其填充到CursorResult.inserted_primary_key
屬性的現有邏輯相容。相比之下,使用UpdateBase.returning()
將導致CursorResult.inserted_primary_key
屬性保持未填充。 -
UpdateBase.return_defaults()
可以針對任何後端呼叫。不支援 RETURNING 的後端將跳過該功能的使用,而不是引發異常,除非傳遞了supplemental_cols
。對於不支援 RETURNING 或目標Table
設定Table.implicit_returning
為False
的後端,CursorResult.returned_defaults
的返回值將為None
。 -
使用
executemany()
呼叫的 INSERT 語句在後端資料庫驅動程式支援 insertmanyvalues 功能的情況下得到支援,這個功能現在大多數包含在 SQLAlchemy 中的後端都支援。當使用executemany
時,CursorResult.returned_defaults_rows
和CursorResult.inserted_primary_key_rows
訪問器將返回插入的預設值和主鍵。1.4 版中的新功能:新增了
CursorResult.returned_defaults_rows
和CursorResult.inserted_primary_key_rows
訪問器。在 2.0 版中,為這些屬性提取和填充資料的底層實現被泛化以受到大多數後端的支援,而在 1.4 版中,它們僅受到psycopg2
驅動程式的支援。
引數:
-
cols
– 可選的列鍵名或Column
列表,充當將被提取的列的過濾器。 -
supplemental_cols
–可選的 RETURNING 表示式列表,與傳遞給
UpdateBase.returning()
方法的形式相同。當存在時,額外的列將包含在 RETURNING 子句中,並且在返回時CursorResult
物件將被“倒帶”,因此像CursorResult.all()
這樣的方法將返回新的行,幾乎就像語句直接使用了UpdateBase.returning()
一樣。但是,與直接使用UpdateBase.returning()
不同,列的順序是未定義的,因此只能使用名稱或Row._mapping
鍵進行定位;它們不能可靠地按位置進行定位。2.0 版中的新功能。
-
sort_by_parameter_order
–對於針對多個引數集執行的批次插入,組織 RETURNING 的結果,使返回的行與傳入的引數集的順序對應。這僅適用於支援方言的 executemany 執行,並通常利用 insertmanyvalues 特性。
2.0.10 版中的新功能。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於對批次插入的 RETURNING 行進行排序的背景資訊
另請參閱
UpdateBase.returning()
CursorResult.returned_defaults
CursorResult.returned_defaults_rows
CursorResult.inserted_primary_key
CursorResult.inserted_primary_key_rows
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
為該語句新增 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
該方法可以多次呼叫以將新條目新增到要返回的表示式列表中。
新版本 1.4.0b2 中新增:該方法可以多次呼叫以將新條目新增到要返回的表示式列表中。
給定的列表示式集應源自於 INSERT、UPDATE 或 DELETE 的目標表。雖然Column
物件是典型的,但元素也可以是表示式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在編譯時,RETURNING 子句或資料庫等效子句將在語句內呈現。對於 INSERT 和 UPDATE,值是新插入/更新的值。對於 DELETE,值是已刪除行的值。
在執行時,要返回的列的值透過結果集可用,並且可以使用CursorResult.fetchone()
等進行迭代。對於不本地支援返回值的 DBAPI(即 cx_oracle),SQLAlchemy 將在結果級別近似此行為,以便提供合理數量的行為中立性。
注意,並非所有的資料庫/DBAPI 都支援 RETURNING。對於不支援的後端,在編譯和/或執行時會引發異常。對於支援它的後端,跨後端的功能差異很大,包括對 executemany()和其他返回多行的語句的限制。請閱讀所使用資料庫的文件註釋,以確定 RETURNING 的可用性。
引數:
-
*cols
– 一系列列、SQL 表示式或整個表實體將被返回。 -
sort_by_parameter_order
–對於針對多個引數集執行的批次 INSERT,請組織 RETURNING 的結果,使返回的行與傳遞的引數集的順序相對應。這僅適用於支援方言的 executemany 執行,並通常利用 insertmanyvalues 功能。
新版本中新增的 2.0.10。
另請參閱
將 RETURNING 行與引數集相關聯 - 關於對批次 INSERT 排序 RETURNING 行的背景(核心級討論)
將 RETURNING 記錄與輸入資料順序相關聯 - 與 ORM Bulk INSERT Statements 的使用示例(ORM 級討論)
另請參閱
UpdateBase.return_defaults()
- 一種針對單行 INSERTs 或 UPDATEs 的有效提取伺服器端預設值和觸發器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 統一教程 中
attribute returning_column_descriptions
返回此 DML 構造與之相對應的列的 外掛啟用 描述,換句話說,作為 UpdateBase.returning()
的一部分建立的表示式。
當使用 ORM 時,此屬性通常很有用,因為它返回了一個包含有關對映實體資訊的擴充套件結構。該部分 從啟用 ORM 的 SELECT 和 DML 語句檢查實體和列 包含了更多的背景知識。
對於 Core 語句,此訪問器返回的結構源自與 UpdateBase.exported_columns
訪問器返回的相同物件:
>>> stmt = insert(user_table).returning(user_table.c.id, user_table.c.name)
>>> stmt.entity_description
[
{
"name": "id",
"type": Integer,
"expr": Column("id", Integer(), table=<user>, ...)
},
{
"name": "name",
"type": String(),
"expr": Column("name", String(), table=<user>, ...)
},
]
從版本 1.4.33 開始新新增。
另請參閱
UpdateBase.entity_description
Select.column_descriptions
- 一個 select()
構造的實體資訊
從啟用 ORM 的 SELECT 和 DML 語句檢查實體和列 - ORM 背景
method with_dialect_options(**opt: Any) → Self
為這個 INSERT/UPDATE/DELETE 物件新增方言選項。
例如:
upd = table.update().dialect_options(mysql_limit=10)
method with_hint(text: str, selectable: _DMLTableArgument | None = None, dialect_name: str = '*') → Self
為這個 INSERT/UPDATE/DELETE 語句新增一個單獨的表提示。
注意
UpdateBase.with_hint()
目前僅適用於 Microsoft SQL Server。對於 MySQL INSERT/UPDATE/DELETE 提示,請使用 UpdateBase.prefix_with()
。
提示文字根據正在使用的資料庫後端在適當的位置呈現,相對於這個語句的主題 Table
,或者可選地傳遞給 Table
的 selectable
引數的 Table
。
dialect_name
選項將限制特定提示的渲染到特定後端。例如,要新增僅在 SQL Server 上生效的提示:
mytable.insert().with_hint("WITH (PAGLOCK)", dialect_name="mssql")
引數:
-
text
– 提示的文字。 -
selectable
– 可選的Table
,指定 UPDATE 或 DELETE 中 FROM 子句的一個元素作為提示的主題 - 僅適用於某些後端。 -
dialect_name
– 預設為*
,如果指定為特定方言的名稱,則僅在使用該方言時應用這些提示。
class sqlalchemy.sql.expression.ValuesBase
為ValuesBase.values()
提供了對 INSERT 和 UPDATE 構造的支援。
成員
select, values()
類簽名
類sqlalchemy.sql.expression.ValuesBase
(sqlalchemy.sql.expression.UpdateBase
)
attribute select: Select[Any] | None = None
INSERT .. FROM SELECT 的 SELECT 語句
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
為 INSERT 語句指定一個固定的 VALUES 子句,或為 UPDATE 指定 SET 子句。
請注意,Insert
和Update
構造支援基於傳遞給Connection.execute()
的引數對 VALUES 和/或 SET 子句進行執行時格式化。但是,ValuesBase.values()
方法可用於將特定一組引數固定到語句中。
對ValuesBase.values()
的多次呼叫將生成一個新的構造,每個構造的引數列表都修改為包括新傳送的引數。在單個引數字典的典型情況下,新傳遞的鍵將替換上一個構造中的相同鍵。在基於列表的“多個值”構造的情況下,每個新值列表都會附加到現有的值列表上。
引數:
-
**kwargs
–表示
Column
的字串鍵的鍵值對對映到要呈現到 VALUES 或 SET 子句中的值:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name")
-
*args
–作為傳遞鍵/值引數的替代方案,可以傳遞一個字典、元組或字典或元組的列表作為單個位置引數,以形成語句的 VALUES 或 SET 子句。接受的形式因此是一個
Insert
或Update
結構而異。對於
Insert
或Update
結構,可以傳遞單個字典,其工作方式與關鍵字引數形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})
同樣適用於任何形式,但更典型的是對於
Insert
結構,還可以接受一個包含表中每一列的條目的元組:users.insert().values((5, "some name"))
Insert
結構還支援傳遞字典或完整表元組的列表,這將在伺服器上呈現較少見的 SQL 語法“多個值” - 此語法在後端,如 SQLite、PostgreSQL、MySQL 等中受支援,但不一定適用於其他後端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])
上述形式將呈現類似於多個 VALUES 語句的內容:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)
需要注意的是,傳遞多個值並不等同於使用傳統的 executemany() 形式。上述語法是一種特殊的語法,通常不常用。要針對多行發出 INSERT 語句,正常方法是將多個值列表傳遞給
Connection.execute()
方法,該方法受到所有資料庫後端的支援,並且通常對於非常大量的引數更有效率。請參閱
傳送多個引數 - 介紹了用於 INSERT 和其他語句的傳統 Core 方法的多個引數集呼叫。
UPDATE 結構還支援以特定順序呈現 SET 引數。有關此功能,請參閱
Update.ordered_values()
方法。請參閱
Update.ordered_values()
SQL 和通用函式
原文:
docs.sqlalchemy.org/en/20/core/functions.html
透過使用 func
名稱空間來呼叫 SQL 函式。請參閱 使用 SQL 函式 教程,瞭解如何使用 func
物件在語句中渲染 SQL 函式的背景知識。
另請參閱
使用 SQL 函式 - 在 SQLAlchemy 統一教程 中
函式 API
SQL 函式的基本 API,提供了 func
名稱空間以及可用於可擴充套件性的類。
物件名稱 | 描述 |
---|---|
AnsiFunction | 以“ansi”格式定義函式,不會渲染括號。 |
Function | 描述一個命名的 SQL 函式。 |
FunctionElement | SQL 函式導向構造的基類。 |
GenericFunction | 定義一個‘通用’函式。 |
register_function(identifier, fn[, package]) | 將可呼叫物件與特定函式名關聯。 |
class sqlalchemy.sql.functions.AnsiFunction
以“ansi”格式定義函式,不會渲染括號。
類簽名
類 sqlalchemy.sql.functions.AnsiFunction
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.Function
描述一個命名的 SQL 函式。
Function
物件通常由 func
生成物件生成。
引數:
-
*clauses
– 形成 SQL 函式呼叫引數的列表示式列表。 -
type_
– 可選的TypeEngine
資料型別物件,將用作由此函式呼叫生成的列表示式的返回值。 -
packagenames
–一個字串,指示在生成 SQL 時要在函式名前新增的包字首名稱。當使用點格式呼叫
func
生成器時會建立這些,例如:func.mypackage.some_function(col1, col2)
另請參閱
使用 SQL 函式 - 在 SQLAlchemy 統一教程 中
func
- 產生註冊或特設的 Function
例項的名稱空間。
GenericFunction
- 允許建立註冊的函式型別。
成員
init()
類簽名
類 sqlalchemy.sql.functions.Function
(sqlalchemy.sql.functions.FunctionElement
)
method __init__(name: str, *clauses: _ColumnExpressionOrLiteralArgument[Any], type_: _TypeEngineArgument[_T] | None = None, packagenames: Tuple[str, ...] | None = None)
構造一個 Function
。
通常使用 func
建構函式來構造新的 Function
例項。
class sqlalchemy.sql.functions.FunctionElement
用於 SQL 函式導向構造的基礎。
這是一個 通用型別,意味著型別檢查器和 IDE 可以指示在此函式的 Result
中期望的型別。參見 GenericFunction
以瞭解如何執行此操作的示例。
另請參閱
使用 SQL 函式 - 在 SQLAlchemy 統一教程 中
Function
- SQL 函式的命名。
func
- 產生註冊或特設的 Function
例項的名稱空間。
GenericFunction
- 允許建立註冊的函式型別。
成員
init(), alias(), as_comparison(), c, clauses, column_valued(), columns, entity_namespace, exported_columns, filter(), over(), scalar_table_valued(), select(), self_group(), table_valued(), within_group(), within_group_type()
類簽名
類sqlalchemy.sql.functions.FunctionElement
(sqlalchemy.sql.expression.Executable
,sqlalchemy.sql.expression.ColumnElement
,sqlalchemy.sql.expression.FromClause
,sqlalchemy.sql.expression.Generative
)
method __init__(*clauses: _ColumnExpressionOrLiteralArgument[Any])
構建一個FunctionElement
。
引數:
-
*clauses
– 列表,包含形成 SQL 函式呼叫引數的列表示式。 -
**kwargs
– 通常由子類消耗的額外 kwargs。
另請參閱
func
Function
method alias(name: str | None = None, joins_implicitly: bool = False) → TableValuedAlias
對這個FunctionElement
構建一個別名。
提示
FunctionElement.alias()
方法是建立“表值”SQL 函式的機制的一部分。但是,大多數用例都透過FunctionElement
上的更高階方法來處理,包括FunctionElement.table_valued()
和FunctionElement.column_valued()
。
此結構將函式包裝在適合 FROM 子句的命名別名中,例如 PostgreSQL 所接受的風格。 還提供了使用特殊的 .column
屬性的列表示式,該屬性可用於在列或 where 子句中引用函式的輸出,例如 PostgreSQL 等後端的標量值。
對於完整的表值表示式,請先使用 FunctionElement.table_valued()
方法來建立命名列。
例如:
>>> from sqlalchemy import func, select, column
>>> data_view = func.unnest([1, 2, 3]).alias("data_view")
>>> print(select(data_view.column))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
FunctionElement.column_valued()
方法為上述模式提供了一種快捷方式:
>>> data_view = func.unnest([1, 2, 3]).column_valued("data_view")
>>> print(select(data_view))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
新版本 1.4.0b2 中新增了 .column
訪問器
引數:
-
name
– 別名,將在 FROM 子句中渲染為AS <name>
-
joins_implicitly
–當為 True 時,可以在 SQL 查詢的 FROM 子句中使用表值函式,而無需顯式連線到其他表,並且不會生成“笛卡爾積”警告。 對於
func.json_each()
等 SQL 函式可能很有用。新版本 1.4.33 中新增。
另請參閱
表值函式 - 在 SQLAlchemy Unified Tutorial 中
FunctionElement.table_valued()
FunctionElement.scalar_table_valued()
FunctionElement.column_valued()
method as_comparison(left_index: int, right_index: int) → FunctionAsBinary
將此表示式解釋為兩個值之間的布林比較。
此方法用於描述 Custom operators based on SQL functions 中的 ORM 用例。
假設的 SQL 函式“is_equal()”,用於比較兩個值是否相等,可以用 Core 表示式語言編寫為:
expr = func.is_equal("a", "b")
如果上面的“is_equal()”是在比較“a”和“b”是否相等,那麼FunctionElement.as_comparison()
方法將被呼叫為:
expr = func.is_equal("a", "b").as_comparison(1, 2)
在上面的例子中,“1”這個整數值是指“is_equal()”函式的第一個引數,“2”這個整數值是指第二個引數。
這將建立一個等效於BinaryExpression
的表示式:
BinaryExpression("a", "b", operator=op.eq)
但是,在 SQL 級別上,它仍然會呈現為“is_equal('a','b')”。
當 ORM 載入相關物件或集合時,需要能夠操作 JOIN 表示式的 ON 子句的“left”和“right”兩邊。此方法的目的是在與relationship.primaryjoin
引數一起使用時,為 ORM 提供也可以向其提供此資訊的 SQL 函式構造。返回值是一個名為FunctionAsBinary
的包含物件。
一個 ORM 示例如下:
class Venue(Base):
__tablename__ = 'venue'
id = Column(Integer, primary_key=True)
name = Column(String)
descendants = relationship(
"Venue",
primaryjoin=func.instr(
remote(foreign(name)), name + "/"
).as_comparison(1, 2) == 1,
viewonly=True,
order_by=name
)
上面,“Venue”類可以透過確定父 Venue 的名稱是否包含在假設的後代值的名稱的開頭來載入後代“Venue”物件,例如“parent1”將匹配到“parent1/child1”,但不會匹配到“parent2/child1”。
可能的用例包括上面給出的“材料化路徑”示例,以及利用特殊的 SQL 函式(例如幾何函式)建立連線條件。
引數:
-
left_index
- 作為表示式“left”側的函式引數的整數基於 1 的索引。 -
right_index
- 作為表示式“right”側的函式引數的整數基於 1 的索引。
版本 1.3 中的新內容。
另請參見
基於 SQL 函式的自定義運算子 - ORM 中的示例用法
attribute c
joins_implicitly
- FunctionElement.columns
的同義詞。
attribute clauses
返回包含此FunctionElement
引數的基礎ClauseList
。
method column_valued(name: str | None = None, joins_implicitly: bool = False) → TableValuedColumn[_T]
將此FunctionElement
作為選擇自身的 FROM 子句的列表示式返回。
例如:
>>> from sqlalchemy import select, func
>>> gs = func.generate_series(1, 5, -1).column_valued()
>>> print(select(gs))
SELECT anon_1
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) AS anon_1
這是的簡寫形式:
gs = func.generate_series(1, 5, -1).alias().column
引數:
-
name
- 分配給生成的別名的可選名稱。如果省略,將使用唯一的匿名名稱。 -
joins_implicitly
–當為 True 時,列值函式的“表”部分可以成為 SQL 查詢中 FROM 子句的成員,而無需對其他表進行顯式 JOIN,並且不會生成“笛卡爾積”警告。可能對諸如
func.json_array_elements()
等 SQL 函式有用。1.4.46 版本中的新功能。
另請參見
列值函式 - 表值函式作為標量列 - 在 SQLAlchemy 統一教程中
列值函式 - 在 PostgreSQL 文件中
FunctionElement.table_valued()
attribute columns
此FunctionElement
匯出的一組列。
這是一個佔位符集合,允許將函式放置在語句的 FROM 子句中:
>>> from sqlalchemy import column, select, func
>>> stmt = select(column('x'), column('y')).select_from(func.myfunction())
>>> print(stmt)
SELECT x, y FROM myfunction()
上述形式是一個已過時的功能,現在已被完全功能的FunctionElement.table_valued()
方法取代;請參閱該方法以獲取詳情。
另請參見
FunctionElement.table_valued()
- 生成表值 SQL 函式表示式。
attribute entity_namespace
覆蓋 FromClause.entity_namespace,因為函式通常是列表示式而不是 FromClauses。
attribute exported_columns
method filter(*criterion: _ColumnExpressionArgument[bool]) → Self | FunctionFilter[_T]
針對此函式生成一個 FILTER 子句。
用於針對支援“FILTER”子句的聚合和視窗函式的資料庫後端。
表示式:
func.count(1).filter(True)
是的縮寫:
from sqlalchemy import funcfilter
funcfilter(func.count(1), True)
另請參見
組內特殊修飾符,過濾器 - 在 SQLAlchemy 統一教程中
FunctionFilter
funcfilter()
method over(*, partition_by: _ByArgument | None = None, order_by: _ByArgument | None = None, rows: Tuple[int | None, int | None] | None = None, range_: Tuple[int | None, int | None] | None = None) → Over[_T]
針對此函式生成一個 OVER 子句。
用於針對聚合或所謂的“視窗”函式,適用於支援視窗函式的資料庫後端。
表示式:
func.row_number().over(order_by='x')
是的縮寫:
from sqlalchemy import over
over(func.row_number(), order_by='x')
有關完整描述,請參閱over()
。
另請參見
over()
使用視窗函式 - 在 SQLAlchemy 統一教程中
method scalar_table_valued(name: str, type_: _TypeEngineArgument[_T] | None = None) → ScalarFunctionColumn[_T]
返回一個列表示式,作為標量表值表示式針對這個FunctionElement
。
返回的表示式類似於從FunctionElement.table_valued()
結構中訪問的單個列返回的表示式,只是不生成 FROM 子句;該函式以類似於標量子查詢的方式呈現。
例如:
>>> from sqlalchemy import func, select
>>> fn = func.jsonb_each("{'k', 'v'}").scalar_table_valued("key")
>>> print(select(fn))
SELECT (jsonb_each(:jsonb_each_1)).key
版本 1.4.0b2 中的新功能。
另見
FunctionElement.table_valued()
FunctionElement.alias()
FunctionElement.column_valued()
method select() → Select
產生針對這個FunctionElement
的select()
構造。
這是的縮寫:
s = select(function_element)
method self_group(against: OperatorType | None = None) → ClauseElement
對這個ClauseElement
應用一個“分組”。
此方法被子類重寫為返回“分組”構造,即括號。特別是,它被“二元”表示式使用,當將它們放入較大的表示式中時,提供對自身的分組,以及當將它們放入另一個select()
構造的 FROM 子句中時,被select()
構造使用。(請注意,子查詢通常應使用Select.alias()
方法建立,因為許多平臺要求巢狀的 SELECT 語句具有名稱)。
隨著表示式組合在一起,self_group()
的應用是自動的 - 終端使用者程式碼不應直接使用此方法。請注意,SQLAlchemy 的子句構造考慮了運算子優先順序 - 因此可能不需要括號,例如,在表示式x OR (y AND z)
中可能不需要括號 - AND 優先於 OR。
ClauseElement
的基本方法self_group()
只是返回自身。
method table_valued(*expr: _ColumnExpressionOrStrLabelArgument[Any], **kw: Any) → TableValuedAlias
返回一個 FunctionElement
的 TableValuedAlias
表示形式,其中新增了表值表示式。
例如:
>>> fn = (
... func.generate_series(1, 5).
... table_valued("value", "start", "stop", "step")
... )
>>> print(select(fn))
SELECT anon_1.value, anon_1.start, anon_1.stop, anon_1.step
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
>>> print(select(fn.c.value, fn.c.stop).where(fn.c.value > 2))
SELECT anon_1.value, anon_1.stop
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
WHERE anon_1.value > :value_1
透過傳遞關鍵字引數“with_ordinality”可以生成一個 WITH ORDINALITY 表示式:
>>> fn = func.generate_series(4, 1, -1).table_valued("gen", with_ordinality="ordinality")
>>> print(select(fn))
SELECT anon_1.gen, anon_1.ordinality
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) WITH ORDINALITY AS anon_1
引數:
-
*expr
- 將新增到結果TableValuedAlias
構造的.c
集合中的一系列字串列名。也可以使用具有或不具有資料型別的column()
物件。 -
name
- 分配給生成的別名的可選名稱。如果省略,將使用唯一的匿名化名稱。 -
with_ordinality
- 存在時,將 WITH ORDINALITY 子句新增到別名,並將給定的字串名稱新增為結果TableValuedAlias
的.c
集合中的列。 -
joins_implicitly
-當為 True 時,可以在 SQL 查詢的 FROM 子句中使用表值函式,而無需對其他表進行顯式的 JOIN,並且不會生成“笛卡爾積”警告。對於 SQL 函式(例如
func.json_each()
)可能很有用。新版本 1.4.33 中的新增功能。
新版本 1.4.0b2 中的新增功能。
另請參見
表值函式 - 在 SQLAlchemy 統一教程 中
表值函式 - 在 PostgreSQL 文件中
FunctionElement.scalar_table_valued()
- FunctionElement.table_valued()
的變體,將完整的表值表示式作為標量列表示式傳遞
FunctionElement.column_valued()
TableValuedAlias.render_derived()
- 使用派生列子句渲染別名,例如 AS name(col1, col2, ...)
method within_group(*order_by: _ColumnExpressionArgument[Any]) → WithinGroup[_T]
生成針對此函式的 WITHIN GROUP (ORDER BY expr) 子句。
用於所謂的“有序集合聚合”和“假設集合聚合”函式,包括 percentile_cont
、rank
、dense_rank
等。
有關完整描述,請參閱 within_group()
。
另請參閱
WITHIN GROUP、FILTER 特殊修飾符 - 在 SQLAlchemy 統一教程 中
method within_group_type(within_group: WithinGroup[_S]) → TypeEngine | None
對於將其返回型別定義為基於 WITHIN GROUP (ORDER BY) 表示式中的條件的型別,由 WithinGroup
構造呼叫。
預設情況下返回 None,在這種情況下,函式的正常.type
被使用。
class sqlalchemy.sql.functions.GenericFunction
定義一個‘通用’函式。
泛型函式是預先定義的 Function
類,在從 func
屬性按名稱呼叫時會自動例項化。請注意,從 func
呼叫任何名稱的效果是自動建立一個新的 Function
例項,給定該名稱。定義 GenericFunction
類的主要用例是為特定名稱的函式指定固定的返回型別。它還可以包括自定義引數解析方案以及其他方法。
GenericFunction
的子類會自動註冊到類的名稱下。例如,使用者定義的函式 as_utc()
將立即可用:
from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.types import DateTime
class as_utc(GenericFunction):
type = DateTime()
inherit_cache = True
print(select(func.as_utc()))
使用者定義的通用函式可以透過在定義 GenericFunction
時指定“package”屬性來組織成包。包含許多函式的第三方庫可能希望這樣做,以避免與其他系統的名稱衝突。例如,如果我們的 as_utc()
函式是包 “time” 的一部分:
class as_utc(GenericFunction):
type = DateTime()
package = "time"
inherit_cache = True
上述函式可以透過使用包名 time
從 func
中獲得:
print(select(func.time.as_utc()))
最後一種選擇是允許從func
中的一個名稱訪問函式,但呈現為不同的名稱。identifier
屬性將覆蓋從func
載入的函式名稱,但將保留name
作為呈現名稱的用法:
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = "ST_Buffer"
identifier = "buffer"
inherit_cache = True
以上函式將呈現如下:
>>> print(func.geo.buffer())
ST_Buffer()
名稱將原樣顯示,但不會加引號,除非名稱包含需要加引號的特殊字元。要在名稱上強制加引號或取消引號,請使用quoted_name
結構:
from sqlalchemy.sql import quoted_name
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = quoted_name("ST_Buffer", True)
identifier = "buffer"
inherit_cache = True
以上函式將呈現為:
>>> print(func.geo.buffer())
"ST_Buffer"()
可以傳遞此類作為泛型型別的類的型別引數,並應與Result
中看到的型別相匹配。例如:
class as_utc(GenericFunction[datetime.datetime]):
type = DateTime()
inherit_cache = True
以上表明以下表示式返回一個datetime
物件:
connection.scalar(select(func.as_utc()))
從版本 1.3.13 開始:在物件的“name”屬性中使用quoted_name
結構現在被識別為引用,因此可以強制對函式名稱進行引用或取消引用。
類簽名
類sqlalchemy.sql.functions.GenericFunction
(sqlalchemy.sql.functions.Function
)
function sqlalchemy.sql.functions.register_function(identifier: str, fn: Type[Function[Any]], package: str = '_default') → None
將可呼叫物件與特定的函式名關聯起來。
通常由 GenericFunction 呼叫,但也可單獨使用,以便將非 Function 構造與func
訪問器關聯起來(即 CAST,EXTRACT)。
選定的“已知”函式
這些是一組常見 SQL 函式的GenericFunction
實現,為每個函式自動設定了預期的返回型別。它們以與func
名稱空間的任何其他成員相同的方式呼叫:
select(func.count("*")).select_from(some_table)
請注意,任何func
未知的名稱都會按原樣生成函式名稱 - SQLAlchemy 對可以呼叫的 SQL 函式沒有限制,不管對 SQLAlchemy 已知還是未知,內建還是使用者定義。本節僅描述 SQLAlchemy 已知引數和返回型別的函式。
物件名稱 | 描述 |
---|---|
aggregate_strings | 實現一個通用的字串聚合函式。 |
array_agg | 對 ARRAY_AGG 函式的支援。 |
char_length | CHAR_LENGTH() SQL 函式。 |
coalesce | |
concat | SQL CONCAT()函式,用於連線字串。 |
count | ANSI COUNT 聚合函式。沒有引數時,發出 COUNT *。 |
cube | 實現CUBE 分組操作。 |
cume_dist | 實現cume_dist 假設集合聚合函式。 |
current_date | CURRENT_DATE() SQL 函式。 |
current_time | CURRENT_TIME() SQL 函式。 |
current_timestamp | CURRENT_TIMESTAMP() SQL 函式。 |
current_user | CURRENT_USER() SQL 函式。 |
dense_rank | 實現dense_rank 假設集合聚合函式。 |
grouping_sets | 實現GROUPING SETS 分組操作。 |
localtime | localtime() SQL 函式。 |
localtimestamp | localtimestamp() SQL 函式。 |
max | SQL MAX()聚合函式。 |
min | SQL MIN()聚合函式。 |
mode | 實現mode 有序集合聚合函式。 |
next_value | 代表“下一個值”,給定一個Sequence 作為其唯一引數。 |
now | SQL now()日期時間函式。 |
percent_rank | 實現percent_rank 假設集合聚合函式。 |
percentile_cont | 實現percentile_cont 有序集合聚合函式。 |
percentile_disc | 實現percentile_disc 有序集合聚合函式。 |
random | RANDOM() SQL 函式。 |
rank | 實現rank 假設集合聚合函式。 |
rollup | 實現ROLLUP 分組操作。 |
session_user | SESSION_USER() SQL 函式。 |
sum | SQL SUM()聚合函式。 |
sysdate | SYSDATE() SQL 函式。 |
user | USER() SQL 函式。 |
class sqlalchemy.sql.functions.aggregate_strings
實現一個通用的字串聚合函式。
此函式將非空值連線成字串,並用分隔符分隔值。
此函式根據每個後端編譯為group_concat()
、string_agg()
或LISTAGG()
等函式。
例如,使用分隔符‘.’的示例用法:
stmt = select(func.aggregate_strings(table.c.str_col, "."))
此函式的返回型別是String
。
類簽名
類sqlalchemy.sql.functions.aggregate_strings
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.array_agg
支援 ARRAY_AGG 函式。
func.array_agg(expr)
構造返回型別為ARRAY
的表示式。
例如:
stmt = select(func.array_agg(table.c.values)[2:5])
參見
array_agg()
- 返回ARRAY
的 PostgreSQL 特定版本,其中新增了 PG 特定的運算子。
類簽名
類sqlalchemy.sql.functions.array_agg
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.char_length
CHAR_LENGTH() SQL 函式。
類簽名
類sqlalchemy.sql.functions.char_length
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.coalesce
類簽名
類sqlalchemy.sql.functions.coalesce
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.concat
SQL CONCAT()函式,用於連線字串。
例如:
>>> print(select(func.concat('a', 'b')))
SELECT concat(:concat_2, :concat_3) AS concat_1
在 SQLAlchemy 中,字串連線更常見地使用 Python 的+
運算子與字串資料型別一起使用,這將呈現特定於後端的連線運算子,例如:
>>> print(select(literal("a") + "b"))
SELECT :param_1 || :param_2 AS anon_1
類簽名
類sqlalchemy.sql.functions.concat
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.count
ANSI COUNT 聚合函式。沒有引數時,發出 COUNT *。
例如:
from sqlalchemy import func
from sqlalchemy import select
from sqlalchemy import table, column
my_table = table('some_table', column('id'))
stmt = select(func.count()).select_from(my_table)
執行stmt
將發出:
SELECT count(*) AS count_1
FROM some_table
類簽名
類sqlalchemy.sql.functions.count
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.cube
實現CUBE
分組操作。
此函式用作語句的 GROUP BY 的一部分,例如Select.group_by()
:
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.cube(table.c.col_1, table.c.col_2))
新增於版本 1.2。
類簽名
類sqlalchemy.sql.functions.cube
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.cume_dist
實現cume_dist
假設集聚合函式。
此函式必須與FunctionElement.within_group()
修飾符一起使用,以提供要操作的排序表示式。
此函式的返回型別為Numeric
。
類簽名
類sqlalchemy.sql.functions.cume_dist
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.current_date
CURRENT_DATE()
SQL 函式。
類簽名
類sqlalchemy.sql.functions.current_date
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.current_time
CURRENT_TIME()
SQL 函式。
類簽名
類sqlalchemy.sql.functions.current_time
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.current_timestamp
CURRENT_TIMESTAMP()
SQL 函式。
類簽名
類sqlalchemy.sql.functions.current_timestamp
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.current_user
CURRENT_USER()
SQL 函式。
類簽名
類sqlalchemy.sql.functions.current_user
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.dense_rank
實現dense_rank
假設集聚合函式。
此函式必須與FunctionElement.within_group()
修飾符一起使用,以提供要操作的排序表示式。
此函式的返回型別為Integer
。
類簽名
類 sqlalchemy.sql.functions.dense_rank
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.grouping_sets
實現 GROUPING SETS
分組操作。
此函式用作語句的 GROUP BY 的一部分,例如 Select.group_by()
:
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.grouping_sets(table.c.col_1, table.c.col_2))
為了按多個集合進行分組,請使用 tuple_()
構造:
from sqlalchemy import tuple_
stmt = select(
func.sum(table.c.value),
table.c.col_1, table.c.col_2,
table.c.col_3
).group_by(
func.grouping_sets(
tuple_(table.c.col_1, table.c.col_2),
tuple_(table.c.value, table.c.col_3),
)
)
版本 1.2 中的新增內容。
類簽名
類 sqlalchemy.sql.functions.grouping_sets
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.localtime
localtime() SQL 函式。
類簽名
類 sqlalchemy.sql.functions.localtime
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.localtimestamp
localtimestamp() SQL 函式。
類簽名
類 sqlalchemy.sql.functions.localtimestamp
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.max
SQL MAX() 聚合函式。
類簽名
類 sqlalchemy.sql.functions.max
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.min
SQL MIN() 聚合函式。
類簽名
類 sqlalchemy.sql.functions.min
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.mode
實現 mode
排序集合聚合函式。
必須與 FunctionElement.within_group()
修改器一起使用,以提供要操作的排序表示式。
此函式的返回型別與排序表示式相同。
類簽名
類 sqlalchemy.sql.functions.mode
(sqlalchemy.sql.functions.OrderedSetAgg
)
class sqlalchemy.sql.functions.next_value
表示“下一個值”,給定 Sequence
作為其唯一引數。
編譯為每個後端的適當函式,或者如果在不提供序列支援的後端上使用,則會引發 NotImplementedError。
類簽名
類sqlalchemy.sql.functions.next_value
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.now
SQL 的 now()日期時間函式。
SQLAlchemy 方言通常會以特定於後端的方式呈現此特定函式,例如將其呈現為CURRENT_TIMESTAMP
。
類簽名
類sqlalchemy.sql.functions.now
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.percent_rank
實現percent_rank
假設集合聚合函式。
必須使用FunctionElement.within_group()
修飾符來提供要操作的排序表示式。
這個函式的返回型別是Numeric
。
類簽名
類sqlalchemy.sql.functions.percent_rank
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.percentile_cont
實現percentile_cont
有序集合聚合函式。
必須使用FunctionElement.within_group()
修飾符來提供要操作的排序表示式。
這個函式的返回型別與排序表示式相同,或者如果引數是一個陣列,則返回排序表示式型別的ARRAY
。
類簽名
類sqlalchemy.sql.functions.percentile_cont
(sqlalchemy.sql.functions.OrderedSetAgg
)
class sqlalchemy.sql.functions.percentile_disc
實現percentile_disc
有序集合聚合函式。
必須使用FunctionElement.within_group()
修飾符來提供要操作的排序表示式。
這個函式的返回型別與排序表示式相同,或者如果引數是一個陣列,則返回排序表示式型別的ARRAY
。
類簽名
類sqlalchemy.sql.functions.percentile_disc
(sqlalchemy.sql.functions.OrderedSetAgg
)
class sqlalchemy.sql.functions.random
RANDOM() SQL 函式。
類簽名
類sqlalchemy.sql.functions.random
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.rank
實現rank
虛擬集合聚合函式。
此函式必須與FunctionElement.within_group()
修飾符一起使用,以提供要操作的排序表示式。
此函式的返回型別為Integer
。
類簽名
類sqlalchemy.sql.functions.rank
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.rollup
實現ROLLUP
分組操作。
此函式用作語句的 GROUP BY 的一部分,例如Select.group_by()
:
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.rollup(table.c.col_1, table.c.col_2))
新版本 1.2 中新增。
類簽名
類sqlalchemy.sql.functions.rollup
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.session_user
SESSION_USER() SQL 函式。
類簽名
類sqlalchemy.sql.functions.session_user
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.sum
SQL 的 SUM()聚合函式。
類簽名
類sqlalchemy.sql.functions.sum
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.sysdate
SYSDATE() SQL 函式。
類簽名
類sqlalchemy.sql.functions.sysdate
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.user
USER() SQL 函式。
類簽名
類sqlalchemy.sql.functions.user
(sqlalchemy.sql.functions.AnsiFunction
)
函式 API
SQL 函式的基本 API,提供了func
名稱空間以及可用於可擴充套件性的類。
物件名稱 | 描述 |
---|---|
AnsiFunction | 定義以“ansi”格式編寫的函式,不渲染括號。 |
Function | 描述一個命名的 SQL 函式。 |
FunctionElement | 面向 SQL 函式構建的基類。 |
GenericFunction | 定義一個“通用”函式。 |
register_function(identifier, fn[, package]) | 將可呼叫物件與特定的 func. 名稱關聯起來。 |
class sqlalchemy.sql.functions.AnsiFunction
在“ansi”格式中定義一個不渲染括號的函式。
類簽名
類 sqlalchemy.sql.functions.AnsiFunction
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.Function
描述一個命名的 SQL 函式。
Function
物件通常是從 func
生成物件生成的。
引數:
-
*clauses
– 形成 SQL 函式呼叫引數的列表示式列表。 -
type_
– 可選的TypeEngine
資料型別物件,將用作由此函式呼叫生成的列表示式的返回值。 -
packagenames
–一個字串,指示在生成 SQL 時要在函式名稱之前新增的包字首名稱。當以點格式呼叫
func
生成器時,會建立這些內容,例如:func.mypackage.some_function(col1, col2)
另請參閱
處理 SQL 函式 - 在 SQLAlchemy 統一教程 中
func
- 產生註冊或臨時 Function
例項的名稱空間。
GenericFunction
- 允許建立已註冊的函式型別。
成員
init()
類簽名
類 sqlalchemy.sql.functions.Function
(sqlalchemy.sql.functions.FunctionElement
)
method __init__(name: str, *clauses: _ColumnExpressionOrLiteralArgument[Any], type_: _TypeEngineArgument[_T] | None = None, packagenames: Tuple[str, ...] | None = None)
構建一個 Function
。
func
結構通常用於構建新的 Function
例項。
class sqlalchemy.sql.functions.FunctionElement
面向 SQL 函式構建的基類。
這是一個通用型別,意味著型別檢查器和整合開發環境可以指示在此函式的 Result
中期望的型別。檢視 GenericFunction
以瞭解如何執行此操作的示例。
另請參閱
使用 SQL 函式 - 在 SQLAlchemy 統一教程 中
Function
- 命名的 SQL 函式。
func
- 生成註冊或臨時的 Function
例項的名稱空間。
GenericFunction
- 允許建立註冊的函式型別。
成員
init(), alias(), as_comparison(), c, clauses, column_valued(), columns, entity_namespace, exported_columns, filter(), over(), scalar_table_valued(), select(), self_group(), table_valued(), within_group(), within_group_type()
類簽名
類 sqlalchemy.sql.functions.FunctionElement
(sqlalchemy.sql.expression.Executable
, sqlalchemy.sql.expression.ColumnElement
, sqlalchemy.sql.expression.FromClause
, sqlalchemy.sql.expression.Generative
)
method __init__(*clauses: _ColumnExpressionOrLiteralArgument[Any])
構建一個 FunctionElement
。
引數:
-
*clauses
– 構成 SQL 函式呼叫引數的列表示式列表。 -
**kwargs
– 通常由子類使用的額外 kwargs。
另請參閱
func
Function
method alias(name: str | None = None, joins_implicitly: bool = False) → TableValuedAlias
根據此 FunctionElement
建立一個 Alias
結構。
提示
FunctionElement.alias()
方法是建立“表值”SQL 函式的機制的一部分。 但是,大多數用例都由 FunctionElement
上的更高階方法覆蓋,包括 FunctionElement.table_valued()
和 FunctionElement.column_valued()
。
此結構將函式包裝在一個適合 FROM 子句的命名別名中,其樣式符合 PostgreSQL 示例。 還提供了一個列表示式,使用特殊的 .column
屬性,該屬性可用於在列或 WHERE 子句中引用函式的輸出,例如 PostgreSQL 這樣的後端中的標量值。
對於完整的表值表示式,首先使用 FunctionElement.table_valued()
方法來建立具名列。
例如:
>>> from sqlalchemy import func, select, column
>>> data_view = func.unnest([1, 2, 3]).alias("data_view")
>>> print(select(data_view.column))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
FunctionElement.column_valued()
方法提供了上述模式的快捷方式:
>>> data_view = func.unnest([1, 2, 3]).column_valued("data_view")
>>> print(select(data_view))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
新於版本 1.4.0b2:新增了 .column
訪問器
引數:
-
name
– 別名,將在 FROM 子句中呈現為AS <name>
-
joins_implicitly
–當為 True 時,可以在 SQL 查詢的 FROM 子句中使用表值函式,而無需對其他表進行顯式 JOIN,並且不會生成“笛卡爾積”警告。 對於諸如
func.json_each()
之類的 SQL 函式可能很有用。新於版本 1.4.33。
另請參閱
表值函式 - 在 SQLAlchemy 統一教程 中
FunctionElement.table_valued()
FunctionElement.scalar_table_valued()
FunctionElement.column_valued()
method as_comparison(left_index: int, right_index: int) → FunctionAsBinary
將此表示式解釋為兩個值之間的布林比較。
此方法用於描述 ORM 用例的基於 SQL 函式的自定義運算子。
一個假設的比較兩個值是否相等的 SQL 函式“is_equal()”將在 Core 表示式語言中編寫為:
expr = func.is_equal("a", "b")
如果上述的“is_equal()”比較的是“a”和“b”的相等性,那麼FunctionElement.as_comparison()
方法將被呼叫如下:
expr = func.is_equal("a", "b").as_comparison(1, 2)
在上面,整數值“1”指的是“is_equal()”函式的第一個引數,整數值“2”指的是第二個引數。
這將建立一個等同於的BinaryExpression
:
BinaryExpression("a", "b", operator=op.eq)
但是,在 SQL 級別上,它仍然呈現為“is_equal('a', 'b')”。
當 ORM 載入相關物件或集合時,需要能夠操作 JOIN 表示式的 ON 子句的“左”和“右”側。此方法的目的是在使用relationship.primaryjoin
引數時,為 ORM 提供一個也可以向其提供此資訊的 SQL 函式構造,返回值是一個名為FunctionAsBinary
的包含物件。
一個 ORM 示例如下:
class Venue(Base):
__tablename__ = 'venue'
id = Column(Integer, primary_key=True)
name = Column(String)
descendants = relationship(
"Venue",
primaryjoin=func.instr(
remote(foreign(name)), name + "/"
).as_comparison(1, 2) == 1,
viewonly=True,
order_by=name
)
在上面的例子中,“Venue”類可以透過確定父級 Venue 的名稱是否包含在假想後代值的名稱的開頭來載入後代“Venue”物件,例如,“parent1”將匹配到“parent1/child1”,但不會匹配到“parent2/child1”。
可能的用例包括上面給出的“materialized path”示例,以及利用特殊的 SQL 函式來建立連線條件,如幾何函式。
引數:
-
left_index
– 函式引數中作為“左側”表示式的整數索引(從 1 開始)。 -
right_index
– 函式引數中作為“右側”表示式的整數索引(從 1 開始)。
版本 1.3 中的新功能。
另請參閱
基於 SQL 函式的自定義運算子 - 在 ORM 中的示例用法
attribute c
FunctionElement.columns
的同義詞。
attribute clauses
返回包含此FunctionElement
引數的ClauseList
的基礎物件。
method column_valued(name: str | None = None, joins_implicitly: bool = False) → TableValuedColumn[_T]
將此FunctionElement
作為從自身選擇的列表示式返回。
例如:
>>> from sqlalchemy import select, func
>>> gs = func.generate_series(1, 5, -1).column_valued()
>>> print(select(gs))
SELECT anon_1
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) AS anon_1
這是的簡寫形式:
gs = func.generate_series(1, 5, -1).alias().column
引數:
-
name
- 可選的名稱,用於分配生成的別名名稱。如果省略,將使用唯一的匿名名稱。 -
joins_implicitly
-當為 True 時,列值函式的“table”部分可以作為 SQL 查詢中 FROM 子句的成員,而不需要對其他表進行顯式 JOIN,並且不會生成“笛卡爾積”警告。 對於諸如
func.json_array_elements()
之類的 SQL 函式可能有用。1.4.46 版中的新功能。
請參閱
列值函式 - 表值函式作為標量列 - 在 SQLAlchemy 統一教程中
列值函式 - 在 PostgreSQL 文件中
FunctionElement.table_valued()
attribute columns
此FunctionElement
匯出的列的集合。
這是一個佔位符集合,允許將函式放置在語句的 FROM 子句中:
>>> from sqlalchemy import column, select, func
>>> stmt = select(column('x'), column('y')).select_from(func.myfunction())
>>> print(stmt)
SELECT x, y FROM myfunction()
上述形式是一個現在已被完全功能的FunctionElement.table_valued()
方法所取代的遺留特性;有關詳細資訊,請參閱該方法。
請參閱
FunctionElement.table_valued()
- 生成表值 SQL 函式表示式。
attribute entity_namespace
覆蓋 FromClause.entity_namespace,因為函式通常是列表示式,而不是 FromClauses。
attribute exported_columns
method filter(*criterion: _ColumnExpressionArgument[bool]) → Self | FunctionFilter[_T]
產生針對此函式的 FILTER 子句。
用於支援“FILTER”子句的資料庫後端中的聚合和視窗函式。
表示式:
func.count(1).filter(True)
是的簡寫形式:
from sqlalchemy import funcfilter
funcfilter(func.count(1), True)
請參閱
特殊修飾符 WITHIN GROUP,FILTER - 在 SQLAlchemy 統一教程中
FunctionFilter
funcfilter()
method over(*, partition_by: _ByArgument | None = None, order_by: _ByArgument | None = None, rows: Tuple[int | None, int | None] | None = None, range_: Tuple[int | None, int | None] | None = None) → Over[_T]
產生針對此函式的 OVER 子句。
用於支援視窗函式的聚合或所謂的“視窗”函式的資料庫後端。
表示式:
func.row_number().over(order_by='x')
是的簡寫形式:
from sqlalchemy import over
over(func.row_number(), order_by='x')
請參閱over()
以獲取完整描述。
請參閱
over()
使用視窗函式 - 在 SQLAlchemy 統一教程中
method scalar_table_valued(name: str, type_: _TypeEngineArgument[_T] | None = None) → ScalarFunctionColumn[_T]
返回一個針對這個FunctionElement
的列表示式作為標量表值表示式。
返回的表示式類似於從FunctionElement.table_valued()
構造中訪問的單個列返回的表示式,除了不生成 FROM 子句;該函式以標量子查詢的方式呈現。
例如:
>>> from sqlalchemy import func, select
>>> fn = func.jsonb_each("{'k', 'v'}").scalar_table_valued("key")
>>> print(select(fn))
SELECT (jsonb_each(:jsonb_each_1)).key
版本 1.4.0b2 中的新功能。
另請參見
FunctionElement.table_valued()
FunctionElement.alias()
FunctionElement.column_valued()
method select() → Select
產生一個針對這個FunctionElement
的select()
構造。
這是一個簡寫:
s = select(function_element)
method self_group(against: OperatorType | None = None) → ClauseElement
對這個ClauseElement
應用一個“分組”。
子類重寫此方法以返回一個“分組”構造,即括號。特別是它被“二元”表示式使用,當它們被放置到更大的表示式中時提供一個圍繞自身的分組,以及當它們被放置到另一個select()
的 FROM 子句中時,由select()
構造使用。(請注意,子查詢通常應該使用Select.alias()
方法建立,因為許多平臺要求巢狀的 SELECT 語句必須被命名)。
隨著表示式的組合,self_group()
的應用是自動的 - 終端使用者程式碼不應該直接使用這個方法。請注意,SQLAlchemy 的子句構造考慮了運算子優先順序 - 因此在表示式中可能不需要括號,例如,x OR (y AND z)
- AND 優先於 OR。
ClauseElement
的基本self_group()
方法只返回自身。
method table_valued(*expr: _ColumnExpressionOrStrLabelArgument[Any], **kw: Any) → TableValuedAlias
返回此FunctionElement
的TableValuedAlias
表示,其中新增了表值表示式。
例如:
>>> fn = (
... func.generate_series(1, 5).
... table_valued("value", "start", "stop", "step")
... )
>>> print(select(fn))
SELECT anon_1.value, anon_1.start, anon_1.stop, anon_1.step
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
>>> print(select(fn.c.value, fn.c.stop).where(fn.c.value > 2))
SELECT anon_1.value, anon_1.stop
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
WHERE anon_1.value > :value_1
透過傳遞關鍵字引數“with_ordinality”可以生成一個 WITH ORDINALITY 表示式:
>>> fn = func.generate_series(4, 1, -1).table_valued("gen", with_ordinality="ordinality")
>>> print(select(fn))
SELECT anon_1.gen, anon_1.ordinality
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) WITH ORDINALITY AS anon_1
引數:
-
*expr
– 一系列將作為列新增到結果的TableValuedAlias
構造中的字串列名。也可以使用具有或不具有資料型別的column()
物件。 -
name
– 分配給生成的別名名稱的可選名稱。如果省略,將使用唯一的匿名化名稱。 -
with_ordinality
– 當存在時,會將WITH ORDINALITY
子句新增到別名中,並且給定的字串名稱將作為列新增到結果的TableValuedAlias
的.c
集合中。 -
joins_implicitly
–當為 True 時,可以在 SQL 查詢的 FROM 子句中使用表值函式,而無需對其他表進行顯式 JOIN,並且不會生成“笛卡爾積”警告。對於諸如
func.json_each()
之類的 SQL 函式可能很有用。新功能在版本 1.4.33 中引入。
新功能在版本 1.4.0b2 中引入。
另請參閱
表值函式 - 在 SQLAlchemy 統一教程中
表值函式 - 在 PostgreSQL 文件中
FunctionElement.scalar_table_valued()
- FunctionElement.table_valued()
的變體,將完整的表值表示式作為標量列表示式傳遞
FunctionElement.column_valued()
TableValuedAlias.render_derived()
- 使用派生列子句呈現別名,例如AS name(col1, col2, ...)
method within_group(*order_by: _ColumnExpressionArgument[Any]) → WithinGroup[_T]
生成一個針對此函式的 WITHIN GROUP (ORDER BY expr) 子句。
用於所謂的“有序集合聚合”和“假設集合聚合”函式,包括percentile_cont
、rank
、dense_rank
等。
詳細描述請參見within_group()
。
另請參見
WITHIN GROUP、FILTER 特殊修飾符 - 在 SQLAlchemy 統一教程中
method within_group_type(within_group: WithinGroup[_S]) → TypeEngine | None
對於將其返回型別定義為基於 WITHIN GROUP (ORDER BY) 表示式中的條件的型別,透過 WithinGroup
構造呼叫。
預設情況下返回 None,此時使用函式的普通.type
。
class sqlalchemy.sql.functions.GenericFunction
定義一個“通用”函式。
通用函式是預先建立的Function
類,在從func
屬性中按名稱呼叫時自動例項化。請注意,從func
呼叫任何名稱都會自動建立一個新的Function
例項,給定該名稱。定義GenericFunction
類的主要用例是為特定名稱的函式指定固定的返回型別。它還可以包括自定義引數解析方案以及其他方法。
GenericFunction
的子類會自動註冊在類的名稱下。例如,使用者定義的函式as_utc()
將立即可用:
from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.types import DateTime
class as_utc(GenericFunction):
type = DateTime()
inherit_cache = True
print(select(func.as_utc()))
使用者定義的通用函式可以透過在定義GenericFunction
時指定“package”屬性來組織到包中。許多函式的第三方庫可能想要使用此功能,以避免與其他系統的名稱衝突。例如,如果我們的 as_utc()
函式是“time”包的一部分:
class as_utc(GenericFunction):
type = DateTime()
package = "time"
inherit_cache = True
上述函式可以透過func
來使用,使用包名time
:
print(select(func.time.as_utc()))
最後一個選項是允許從func
中的一個名稱訪問該函式,但呈現為不同的名稱。 identifier
屬性將覆蓋從func
載入時用於訪問函式的名稱,但將保留使用 name
作為呈現名稱的用法:
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = "ST_Buffer"
identifier = "buffer"
inherit_cache = True
上述函式將呈現如下:
>>> print(func.geo.buffer())
ST_Buffer()
名稱將按原樣呈現,但如果名稱包含需要引用的特殊字元,則不會引用。要強制對名稱進行引用或取消引用,請使用 quoted_name
結構:
from sqlalchemy.sql import quoted_name
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = quoted_name("ST_Buffer", True)
identifier = "buffer"
inherit_cache = True
上述函式將呈現為:
>>> print(func.geo.buffer())
"ST_Buffer"()
此類的型別引數作為 通用型別 可以傳遞,並且應該與 Result
中看到的型別匹配。例如:
class as_utc(GenericFunction[datetime.datetime]):
type = DateTime()
inherit_cache = True
以上表明以下表示式返回一個 datetime
物件:
connection.scalar(select(func.as_utc()))
從版本 1.3.13 開始:當與物件的“name”屬性一起使用時,quoted_name
結構現在被識別為引用,因此可以強制對函式名稱進行引用。
類簽名
類sqlalchemy.sql.functions.GenericFunction
(sqlalchemy.sql.functions.Function
)
function sqlalchemy.sql.functions.register_function(identifier: str, fn: Type[Function[Any]], package: str = '_default') → None
將可呼叫物件與特定的函式名稱關聯起來。
通常由 GenericFunction 呼叫,但也可以單獨使用,以便將非 Function 結構與func
訪問器關聯起來(例如 CAST、EXTRACT)。
選定的“已知”函式
這些是一組選定的常見 SQL 函式的GenericFunction
實現,為每個函式自動設定了預期的返回型別。它們以與func
名稱空間的任何其他成員相同的方式呼叫:
select(func.count("*")).select_from(some_table)
請注意,任何未知於func
的名稱都會按原樣生成函式名稱 - 對於可以呼叫的 SQL 函式,對 SQLAlchemy 有無所謂是否知道它們,內建或使用者定義的沒有限制。這裡的部分僅描述了 SQLAlchemy 已經知道正在使用什麼引數和返回型別的函式。
物件名稱 | 描述 |
---|---|
aggregate_strings | 實現一個通用的字串聚合函式。 |
array_agg | 支援 ARRAY_AGG 函式。 |
char_length | CHAR_LENGTH() SQL 函式。 |
coalesce | |
concat | SQL CONCAT() 函式,用於連線字串。 |
count | ANSI COUNT 聚合函式。沒有引數時,發出 COUNT *。 |
cube | 實現CUBE 分組操作。 |
cume_dist | 實現cume_dist 假設集聚合函式。 |
current_date | CURRENT_DATE() SQL 函式。 |
current_time | CURRENT_TIME() SQL 函式。 |
current_timestamp | CURRENT_TIMESTAMP() SQL 函式。 |
current_user | CURRENT_USER() SQL 函式。 |
dense_rank | 實現dense_rank 假設集聚合函式。 |
grouping_sets | 實現GROUPING SETS 分組操作。 |
localtime | localtime() SQL 函式。 |
localtimestamp | localtimestamp() SQL 函式。 |
max | SQL MAX() 聚合函式。 |
min | SQL MIN() 聚合函式。 |
mode | 實現mode 有序集聚合函式。 |
next_value | 代表“下一個值”,以Sequence 作為其唯一引數。 |
now | SQL now() 日期時間函式。 |
percent_rank | 實現percent_rank 假設集聚合函式。 |
percentile_cont | 實現percentile_cont 有序集聚合函式。 |
percentile_disc | 實現percentile_disc 有序集聚合函式。 |
random | RANDOM() SQL 函式。 |
rank | 實現rank 假設集聚合函式。 |
rollup | 實現ROLLUP 分組操作。 |
session_user | SESSION_USER() SQL 函式。 |
sum | SQL SUM() 聚合函式。 |
sysdate | SYSDATE() SQL 函式。 |
user | USER() SQL 函式。 |
class sqlalchemy.sql.functions.aggregate_strings
實現一個通用的字串聚合函式。
此函式將非空值連線為一個字串,並用分隔符分隔值。
此函式根據每個後端編譯為group_concat()
、string_agg()
或LISTAGG()
等函式。
例如,使用分隔符‘.’的示例用法:
stmt = select(func.aggregate_strings(table.c.str_col, "."))
此函式的返回型別為String
。
類簽名
類sqlalchemy.sql.functions.aggregate_strings
(sqlalchemy.sql.functions.GenericFunction
)。
class sqlalchemy.sql.functions.array_agg
支援 ARRAY_AGG 函式。
func.array_agg(expr)
構造返回型別為ARRAY
的表示式。
例如:
stmt = select(func.array_agg(table.c.values)[2:5])
另請參閱
array_agg()
- 返回ARRAY
的 PostgreSQL 特定版本,其中新增了 PG 特定運算子。
類簽名
類sqlalchemy.sql.functions.array_agg
(sqlalchemy.sql.functions.GenericFunction
)。
class sqlalchemy.sql.functions.char_length
SQL 函式CHAR_LENGTH()
.
類簽名
類sqlalchemy.sql.functions.char_length
(sqlalchemy.sql.functions.GenericFunction
)。
class sqlalchemy.sql.functions.coalesce
類簽名
類sqlalchemy.sql.functions.coalesce
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)。
class sqlalchemy.sql.functions.concat
SQL CONCAT()函式,用於連線字串。
例如:
>>> print(select(func.concat('a', 'b')))
SELECT concat(:concat_2, :concat_3) AS concat_1
在 SQLAlchemy 中,使用 Python 的+
運算子與字串資料型別更常見,這將呈現特定於後端的連線運算子,例如:
>>> print(select(literal("a") + "b"))
SELECT :param_1 || :param_2 AS anon_1
類簽名
類sqlalchemy.sql.functions.concat
(sqlalchemy.sql.functions.GenericFunction
)。
class sqlalchemy.sql.functions.count
ANSI COUNT 聚合函式。沒有引數時,發出 COUNT *。
例如:
from sqlalchemy import func
from sqlalchemy import select
from sqlalchemy import table, column
my_table = table('some_table', column('id'))
stmt = select(func.count()).select_from(my_table)
執行stmt
將發出:
SELECT count(*) AS count_1
FROM some_table
類簽名
類sqlalchemy.sql.functions.count
(sqlalchemy.sql.functions.GenericFunction
)。
class sqlalchemy.sql.functions.cube
實現CUBE
分組操作。
此函式用作語句的 GROUP BY 的一部分,例如 Select.group_by()
:
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.cube(table.c.col_1, table.c.col_2))
新版本 1.2 中新增。
類簽名
class sqlalchemy.sql.functions.cube
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.cume_dist
實現 cume_dist
假設集聚合函式。
必須使用 FunctionElement.within_group()
修飾符來提供一個排序表示式以進行操作。
該函式的返回型別是 Numeric
。
類簽名
class sqlalchemy.sql.functions.cume_dist
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.current_date
CURRENT_DATE() SQL 函式。
類簽名
class sqlalchemy.sql.functions.current_date
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.current_time
CURRENT_TIME() SQL 函式。
類簽名
class sqlalchemy.sql.functions.current_time
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.current_timestamp
CURRENT_TIMESTAMP() SQL 函式。
類簽名
class sqlalchemy.sql.functions.current_timestamp
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.current_user
CURRENT_USER() SQL 函式。
類簽名
class sqlalchemy.sql.functions.current_user
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.dense_rank
實現 dense_rank
假設集聚合函式。
必須使用 FunctionElement.within_group()
修飾符來提供一個排序表示式以進行操作。
該函式的返回型別是 Integer
。
類簽名
類sqlalchemy.sql.functions.dense_rank
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.grouping_sets
實現 GROUPING SETS
分組操作。
此函式用作語句的 GROUP BY 的一部分,例如 Select.group_by()
:
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.grouping_sets(table.c.col_1, table.c.col_2))
要按多個集合分組,請使用tuple_()
結構:
from sqlalchemy import tuple_
stmt = select(
func.sum(table.c.value),
table.c.col_1, table.c.col_2,
table.c.col_3
).group_by(
func.grouping_sets(
tuple_(table.c.col_1, table.c.col_2),
tuple_(table.c.value, table.c.col_3),
)
)
版本 1.2 中的新功能。
類簽名
類sqlalchemy.sql.functions.grouping_sets
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.localtime
localtime() SQL 函式。
類簽名
類sqlalchemy.sql.functions.localtime
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.localtimestamp
localtimestamp() SQL 函式。
類簽名
類sqlalchemy.sql.functions.localtimestamp
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.max
SQL MAX() 聚合函式。
類簽名
類sqlalchemy.sql.functions.max
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.min
SQL MIN() 聚合函式。
類簽名
類sqlalchemy.sql.functions.min
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.mode
實現 mode
有序集合聚合函式。
這個函式必須與FunctionElement.within_group()
修飾符一起使用,以提供要操作的排序表示式。
此函式的返回型別與排序表示式相同。
類簽名
類sqlalchemy.sql.functions.mode
(sqlalchemy.sql.functions.OrderedSetAgg
)
class sqlalchemy.sql.functions.next_value
代表給定Sequence
作為其唯一引數的‘下一個值’。
在每個後端編譯成適當的函式,或者如果在不提供序列支援的後端上使用則會引發 NotImplementedError。
類簽名
類sqlalchemy.sql.functions.next_value
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.now
SQL 現在()日期時間函式。
SQLAlchemy 方言通常以特定於後端的方式呈現此特定函式,例如將其呈現為CURRENT_TIMESTAMP
。
類簽名
類sqlalchemy.sql.functions.now
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.percent_rank
實現percent_rank
假設集合聚合函式。
必須使用FunctionElement.within_group()
修飾符來提供要操作的排序表示式。
此函式的返回型別是Numeric
。
類簽名
類sqlalchemy.sql.functions.percent_rank
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.percentile_cont
實現percentile_cont
有序集合聚合函式。
必須使用FunctionElement.within_group()
修飾符來提供要操作的排序表示式。
此函式的返回型別與排序表示式相同,或者如果引數是陣列,則為排序表示式型別的ARRAY
。
類簽名
類sqlalchemy.sql.functions.percentile_cont
(sqlalchemy.sql.functions.OrderedSetAgg
)
class sqlalchemy.sql.functions.percentile_disc
實現percentile_disc
有序集合聚合函式。
必須使用FunctionElement.within_group()
修飾符來提供要操作的排序表示式。
此函式的返回型別與排序表示式相同,或者如果引數是陣列,則為排序表示式型別的ARRAY
。
類簽名
類sqlalchemy.sql.functions.percentile_disc
(sqlalchemy.sql.functions.OrderedSetAgg
)
class sqlalchemy.sql.functions.random
RANDOM() SQL 函式。
類簽名
類 sqlalchemy.sql.functions.random
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.rank
實現 rank
虛擬集合聚合函式。
此函式必須與 FunctionElement.within_group()
修改器一起使用,以提供要操作的排序表示式。
此函式的返回型別是 Integer
。
類簽名
類 sqlalchemy.sql.functions.rank
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.rollup
實現 ROLLUP
分組操作。
此函式用作語句的 GROUP BY 的一部分,例如 Select.group_by()
:
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.rollup(table.c.col_1, table.c.col_2))
新版本 1.2 中新增。
類簽名
類 sqlalchemy.sql.functions.rollup
(sqlalchemy.sql.functions.GenericFunction
)
class sqlalchemy.sql.functions.session_user
SESSION_USER() SQL 函式。
類簽名
類 sqlalchemy.sql.functions.session_user
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.sum
SQL SUM() 聚合函式。
類簽名
類 sqlalchemy.sql.functions.sum
(sqlalchemy.sql.functions.ReturnTypeFromArgs
)
class sqlalchemy.sql.functions.sysdate
SYSDATE() SQL 函式。
類簽名
類 sqlalchemy.sql.functions.sysdate
(sqlalchemy.sql.functions.AnsiFunction
)
class sqlalchemy.sql.functions.user
USER() SQL 函式。
類簽名
類 sqlalchemy.sql.functions.user
(sqlalchemy.sql.functions.AnsiFunction
)
自定義 SQL 構造和編譯擴充套件
原文:
docs.sqlalchemy.org/en/20/core/compiler.html
提供了用於建立自定義 ClauseElements 和編譯器的 API。
概要
使用涉及建立一個或多個ClauseElement
子類和一個或多個定義其編譯的可呼叫物件:
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ColumnClause
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
在上面,MyColumn
擴充套件了ColumnClause
,這是命名列物件的基本表示式元素。compiles
裝飾器向MyColumn
類註冊自身,以便在將物件編譯為字串時呼叫它:
from sqlalchemy import select
s = select(MyColumn('x'), MyColumn('y'))
print(str(s))
產生:
SELECT [x], [y]
方言特定的編譯規則
編譯器也可以是特定於方言的。將為使用的方言呼叫適當的編譯器:
from sqlalchemy.schema import DDLElement
class AlterColumn(DDLElement):
inherit_cache = False
def __init__(self, column, cmd):
self.column = column
self.cmd = cmd
@compiles(AlterColumn)
def visit_alter_column(element, compiler, **kw):
return "ALTER COLUMN %s ..." % element.column.name
@compiles(AlterColumn, 'postgresql')
def visit_alter_column(element, compiler, **kw):
return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name,
element.column.name)
當使用任何postgresql
方言時,第二個visit_alter_table
將被呼叫。
編譯自定義表示式構造的子元素
compiler
引數是正在使用的Compiled
物件。可以檢查此物件的任何有關進行中編譯的資訊,包括compiler.dialect
、compiler.statement
等。SQLCompiler
和DDLCompiler
都包括一個process()
方法,可用於編譯嵌入屬性:
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
insert = InsertFromSelect(t1, select(t1).where(t1.c.x>5))
print(insert)
產生:
"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z
FROM mytable WHERE mytable.x > :x_1)"
注意
上述的InsertFromSelect
構造僅是一個示例,這種實際功能已經可以使用Insert.from_select()
方法。
在 SQL 和 DDL 編譯器之間進行交叉編譯
SQL 和 DDL 構造分別使用不同的基本編譯器 - SQLCompiler
和DDLCompiler
。一個常見的需求是從 DDL 表示式中訪問 SQL 表示式的編譯規則。DDLCompiler
包含一個訪問器sql_compiler
,因此我們可以生成嵌入 SQL 表示式的 CHECK 約束,如下所示:
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
)
在上面,我們在SQLCompiler.process()
中呼叫的過程步驟中新增了一個額外的標誌,即literal_binds
標誌。這表示任何引用BindParameter
物件或其他“literal”物件(如引用字串或整數的物件)的 SQL 表示式應該原地呈現,而不是作為繫結引數引用;在發出 DDL 時,通常不支援繫結引數。
更改現有構造的預設編譯
編譯器擴充套件同樣適用於現有的結構。當覆蓋內建 SQL 結構的編譯時,@compiles 裝飾器會呼叫適當的類(確保使用類,即 Insert
或 Select
,而不是建立函式,比如 insert()
或 select()
)。
在新的編譯函式中,要獲取“原始”的編譯例程,使用適當的 visit_XXX 方法 - 這是因為編譯器.process() 將呼叫重寫的例程並導致無限迴圈。比如,要向所有的插入語句新增“字首”:
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
上述編譯器在編譯時會在所有的 INSERT 語句前加上“某個字首”。
更改型別的編譯
compiler
也適用於型別,比如下面我們為 String
/VARCHAR
實現了 MS-SQL 特定的 ‘max’ 關鍵字:
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
def compile_varchar(element, compiler, **kw):
if element.length == 'max':
return "VARCHAR('max')"
else:
return compiler.visit_VARCHAR(element, **kw)
foo = Table('foo', metadata,
Column('data', VARCHAR('max'))
)
子類化指南
使用編譯器擴充套件的一個重要部分是子類化 SQLAlchemy 表示式結構。為了使這更容易,表示式和模式包含一組旨在用於常見任務的“基礎”。概要如下:
-
ClauseElement
- 這是根表示式類。任何 SQL 表示式都可以從這個基類派生,並且對於長一些的構造,比如專門的 INSERT 語句,這可能是最好的選擇。 -
ColumnElement
- 所有“類似列”的元素的根。你在 SELECT 語句的“列”子句中(以及 order by 和 group by)放置的任何東西都可以從這個派生 - 該物件將自動具有 Python 的“比較”行為。ColumnElement
類希望有一個type
成員,該成員是表示式的返回型別。這可以在建構函式的例項級別或類級別上建立:class timestamp(ColumnElement): type = TIMESTAMP() inherit_cache = True
-
FunctionElement
- 這是ColumnElement
和“from 子句”類似物件的混合體,並表示 SQL 函式或儲存過程型別的呼叫。由於大多數資料庫支援“SELECT FROM <某個函式>”這樣的語句,FunctionElement
新增了在select()
構造的 FROM 子句中使用的能力:from sqlalchemy.sql.expression import FunctionElement class coalesce(FunctionElement): name = 'coalesce' inherit_cache = True @compiles(coalesce) def compile(element, compiler, **kw): return "coalesce(%s)" % compiler.process(element.clauses, **kw) @compiles(coalesce, 'oracle') def compile(element, compiler, **kw): if len(element.clauses) > 2: raise TypeError("coalesce only supports two arguments on Oracle") return "nvl(%s)" % compiler.process(element.clauses, **kw)
-
ExecutableDDLElement
- 所有 DDL 表示式的根,比如 CREATE TABLE,ALTER TABLE 等。ExecutableDDLElement
的子類的編譯由DDLCompiler
發出,而不是由SQLCompiler
發出。ExecutableDDLElement
也可以與DDLEvents.before_create()
和DDLEvents.after_create()
等事件鉤子一起用作事件鉤子,允許在 CREATE TABLE 和 DROP TABLE 序列期間自動呼叫構造。另請參見
自定義 DDL - 包含將
DDL
物件(它們本身是ExecutableDDLElement
例項)與DDLEvents
事件鉤子相關聯的示例。 -
Executable
- 這是一個 mixin,應該與任何表示可以直接傳遞給execute()
方法的“獨立”SQL 語句的表示式類一起使用。它已經隱含在DDLElement
和FunctionElement
中。
上述大部分構造也響應 SQL 語句快取。子類構造將希望為物件定義快取行為,這通常意味著將標誌inherit_cache
設定為False
或True
的值。有關背景資訊,請參見下一節為自定義構造啟用快取支援。
為自定義構造啟用快取支援
從版本 1.4 開始,SQLAlchemy 包括一個 SQL 編譯快取設施,它將允許等效的 SQL 構造快取它們的字串形式,以及用於從語句中獲取結果的其他結構資訊。
如在物件不會生成快取鍵,效能影響中討論的原因,該快取系統的實現對於在快取系統中包含自定義 SQL 構造和/或子類採取了保守的方法。這包括任何使用者定義的 SQL 構造,包括此擴充套件的所有示例,除非它們明確宣告能夠這樣做,否則預設情況下不會參與快取。當在特定子類的類級別設定HasCacheKey.inherit_cache
屬性為True
時,將指示該類的例項可以安全地進行快取,使用直接父類的快取鍵生成方案。例如,這適用於先前指示的“概要”示例:
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
上面,MyColumn
類不包含任何影響其 SQL 編譯的新狀態;MyColumn
例項的快取鍵將利用ColumnClause
超類的快取鍵,這意味著它將考慮物件的類(MyColumn
)、物件的字串名稱和資料型別:
>>> MyColumn("some_name", String())._generate_cache_key()
CacheKey(
key=('0', <class '__main__.MyColumn'>,
'name', 'some_name',
'type', (<class 'sqlalchemy.sql.sqltypes.String'>,
('length', None), ('collation', None))
), bindparams=[])
對於那些在許多更大語句中可能被大量使用作為元件的物件,比如Column
子類和自定義 SQL 資料型別,儘可能啟用快取非常重要,否則可能會對效能產生負面影響。
一個包含影響其 SQL 編譯的狀態的物件示例是在編譯自定義表示式構造的子元素中所示的一個示例;這是一個將Table
和Select
構造組合在一起的“INSERT FROM SELECT”構造,每個構造獨立影響構造的 SQL 字串生成。對於這個類,示例說明它根本不參與快取:
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
雖然上述InsertFromSelect
也可能生成由Table
和Select
元件組合而成的快取鍵,但目前該 API 並不完全公開。然而,對於“INSERT FROM SELECT”構造,它僅用於特定操作,快取並不像前面的示例那樣關鍵。
對於在相對孤立並且通常是獨立的物件,例如自定義 DML 構造,如 “INSERT FROM SELECT”,快取通常不那麼關鍵,因為對於這種構造缺乏快取僅對該特定操作具有區域性影響。
更多示例
“UTC 時間戳”函式
一個類似於 “CURRENT_TIMESTAMP” 的函式,但應用適當的轉換,使時間為 UTC 時間。時間戳最好儲存在關係型資料庫中作為 UTC,不帶時區。UTC 使您的資料庫在夏令時結束時不會認為時間已經倒退,不帶時區是因為時區就像字元編碼 - 最好只在應用程式的端點(即在使用者輸入時轉換為 UTC,在顯示時重新應用所需的時區)應用它們。
對於 PostgreSQL 和 Microsoft SQL Server:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
示例用法:
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
metadata = MetaData()
event = Table("event", metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
)
“GREATEST”函式
“GREATEST”函式接受任意數量的引數,並返回具有最高值的引數 - 它等同於 Python 的 max
函式。與僅容納兩個引數的基於 CASE 的版本相比,SQL 標準版本:
from sqlalchemy.sql import expression, case
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
示例用法:
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
“false” 表示式
渲染“false”常量表示式,對於沒有“false”常量的平臺,渲染為“0”:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
def int_false(element, compiler, **kw):
return "0"
示例用法:
from sqlalchemy import select, union_all
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
)
物件名稱 | 描述 |
---|---|
compiles(class_, *specs) | 為給定ClauseElement 型別註冊函式作為編譯器。 |
deregister(class_) | 刪除與給定ClauseElement 型別關聯的所有自定義編譯器。 |
function sqlalchemy.ext.compiler.compiles(class_, *specs)
為給定ClauseElement
型別註冊函式作為編譯器。
function sqlalchemy.ext.compiler.deregister(class_)
刪除與給定ClauseElement
型別關聯的所有自定義編譯器。
概要
使用涉及建立一個或多個ClauseElement
子類和一個或多個定義其編譯的可呼叫物件:
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ColumnClause
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
上面,MyColumn
擴充套件了ColumnClause
,命名列物件的基本表示式元素。compiles
裝飾器將自身註冊到 MyColumn
類,以便在物件編譯為字串時呼叫它:
from sqlalchemy import select
s = select(MyColumn('x'), MyColumn('y'))
print(str(s))
產生:
SELECT [x], [y]
特定於方言的編譯規則
編譯器也可以是特定於方言的。將為使用的方言呼叫適當的編譯器:
from sqlalchemy.schema import DDLElement
class AlterColumn(DDLElement):
inherit_cache = False
def __init__(self, column, cmd):
self.column = column
self.cmd = cmd
@compiles(AlterColumn)
def visit_alter_column(element, compiler, **kw):
return "ALTER COLUMN %s ..." % element.column.name
@compiles(AlterColumn, 'postgresql')
def visit_alter_column(element, compiler, **kw):
return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name,
element.column.name)
當使用任何 postgresql
方言時,將呼叫第二個 visit_alter_table
。
編譯自定義表示式結構的子元素
compiler
引數是正在使用的 Compiled
物件。此物件可以用於檢查關於正在進行的編譯的任何資訊,包括 compiler.dialect
、compiler.statement
等。SQLCompiler
和 DDLCompiler
都包含一個 process()
方法,可用於編譯嵌入屬性:
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
insert = InsertFromSelect(t1, select(t1).where(t1.c.x>5))
print(insert)
產生:
"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z
FROM mytable WHERE mytable.x > :x_1)"
注意
上述的 InsertFromSelect
構造只是一個例子,實際功能已經可以使用 Insert.from_select()
方法實現。
在 SQL 和 DDL 編譯器之間進行交叉編譯
SQL 和 DDL 構造使用不同的基礎編譯器 - SQLCompiler
和 DDLCompiler
進行編譯。常見的需要是從 DDL 表示式中訪問 SQL 表示式的編譯規則。因此,DDLCompiler
包含一個訪問器 sql_compiler
,如下所示,我們生成一個嵌入了 SQL 表示式的 CHECK 約束:
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
)
在上面的例子中,我們在由 SQLCompiler.process()
呼叫的處理步驟中新增了一個額外的標誌,即 literal_binds
標誌。這表示任何引用 BindParameter
物件或其他“文字”物件(如引用字串或整數的物件)的 SQL 表示式應該就地渲染,而不是作為一個繫結引數引用;在發出 DDL 時,通常不支援繫結引數。
在 SQL 和 DDL 編譯器之間進行交叉編譯
SQL 和 DDL 構造使用不同的基礎編譯器 - SQLCompiler
和 DDLCompiler
進行編譯。常見的需要是從 DDL 表示式中訪問 SQL 表示式的編譯規則。因此,DDLCompiler
包含一個訪問器 sql_compiler
,如下所示,我們生成一個嵌入了 SQL 表示式的 CHECK 約束:
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
)
在上面的例子中,我們在由 SQLCompiler.process()
呼叫的處理步驟中新增了一個額外的標誌,即 literal_binds
標誌。這表示任何引用 BindParameter
物件或其他“文字”物件(如引用字串或整數的物件)的 SQL 表示式應該就地渲染,而不是作為一個繫結引數引用;在發出 DDL 時,通常不支援繫結引數。
更改現有構造的預設編譯
編譯器擴充套件同樣適用於現有構造。當重寫內建 SQL 構造的編譯時,@compiles 裝飾器會在適當的類上呼叫(確保使用類,即 Insert
或 Select
,而不是建立函式,如 insert()
或 select()
)。
在新的編譯函式中,要獲取“原始”編譯例程,使用適當的 visit_XXX 方法 - 這是因為編譯器.process() 將呼叫重寫例程並導致無限迴圈。例如,要向所有插入語句新增“字首”:
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
上述編譯器在編譯時將所有 INSERT 語句字首為“some prefix”。
更改型別的編譯
compiler
也適用於型別,比如下面我們為 String
/VARCHAR
實現 MS-SQL 特定的 ‘max’ 關鍵字:
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
def compile_varchar(element, compiler, **kw):
if element.length == 'max':
return "VARCHAR('max')"
else:
return compiler.visit_VARCHAR(element, **kw)
foo = Table('foo', metadata,
Column('data', VARCHAR('max'))
)
子類指南
使用編譯器擴充套件的一個重要部分是子類化 SQLAlchemy 表示式構造。為了使這更容易,表示式和模式包含一組用於常見任務的“基類”。概要如下:
-
ClauseElement
- 這是根表示式類。任何 SQL 表示式都可以從這個基類派生,對於像專門的 INSERT 語句這樣的較長構造來說,這可能是最好的選擇。 -
ColumnElement
- 所有“列樣”元素的根。您在 SELECT 語句的“columns”子句中(以及 order by 和 group by)中放置的任何內容都可以從這裡派生 - 該物件將自動具有 Python 的“比較”行為。ColumnElement
類希望有一個type
成員,該成員是表示式的返回型別。這可以在建構函式的例項級別或在類級別(如果通常是常量)中建立:class timestamp(ColumnElement): type = TIMESTAMP() inherit_cache = True
-
FunctionElement
- 這是ColumnElement
和“from clause”類似物件的混合體,表示 SQL 函式或儲存過程型別的呼叫。由於大多數資料庫支援類似“SELECT FROM”的語句, FunctionElement
新增了在select()
構造的 FROM 子句中使用的能力:from sqlalchemy.sql.expression import FunctionElement class coalesce(FunctionElement): name = 'coalesce' inherit_cache = True @compiles(coalesce) def compile(element, compiler, **kw): return "coalesce(%s)" % compiler.process(element.clauses, **kw) @compiles(coalesce, 'oracle') def compile(element, compiler, **kw): if len(element.clauses) > 2: raise TypeError("coalesce only supports two arguments on Oracle") return "nvl(%s)" % compiler.process(element.clauses, **kw)
-
ExecutableDDLElement
- 所有 DDL 表示式的根,比如 CREATE TABLE,ALTER TABLE 等。ExecutableDDLElement
的子類的編譯由DDLCompiler
發出,而不是SQLCompiler
。ExecutableDDLElement
還可以與諸如DDLEvents.before_create()
和DDLEvents.after_create()
等事件鉤子一起用作事件鉤子,允許在 CREATE TABLE 和 DROP TABLE 序列期間自動呼叫構造。另請參閱
自定義 DDL - 包含將
DDL
物件(它們本身是ExecutableDDLElement
例項)與DDLEvents
事件鉤子相關聯的示例。 -
Executable
- 這是一個混合類,應該與表示“獨立”SQL 語句的任何表示式類一起使用,可以直接傳遞給execute()
方法。 它已經隱式地存在於DDLElement
和FunctionElement
中。
上述大多數構造也會響應 SQL 語句快取。 子類化的構造將希望為物件定義快取行為,這通常意味著將標誌 inherit_cache
設定為 False
或 True
的值。 有關背景資訊,請參見下一節 為自定義構造啟用快取支援。
為自定義構造啟用快取支援
截至版本 1.4,SQLAlchemy 包括一個 SQL 編譯快取功能,它將允許等效的 SQL 構造快取它們的字串形式,以及用於從語句獲取結果的其他結構資訊。
由於討論的原因在物件不會生成快取鍵,效能影響,這個快取系統的實現採用了一種保守的方式來包括自定義 SQL 構造和/或子類在快取系統中。這包括任何使用者定義的 SQL 構造,包括此擴充套件的所有示例,預設情況下將不參與快取,除非它們明確宣告能夠參與快取。當HasCacheKey.inherit_cache
屬性在特定子類的類級別上設定為True
時,將表示此類的例項可以安全地快取,使用其直接超類的快取鍵生成方案。例如,這適用於先前指示的“概要”示例:
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
在上述示例中,MyColumn
類不包含任何影響其 SQL 編譯的新狀態;MyColumn
例項的快取鍵將利用 ColumnClause
超類的快取鍵,這意味著它將考慮物件的類(MyColumn
)、物件的字串名稱和資料型別:
>>> MyColumn("some_name", String())._generate_cache_key()
CacheKey(
key=('0', <class '__main__.MyColumn'>,
'name', 'some_name',
'type', (<class 'sqlalchemy.sql.sqltypes.String'>,
('length', None), ('collation', None))
), bindparams=[])
對於可能在許多較大語句中自由使用的物件,例如 Column
子類和自定義 SQL 資料型別,儘可能啟用快取是很重要的,否則可能會對效能產生負面影響。
一個包含影響其 SQL 編譯的狀態的物件示例是在編譯自定義表示式結構的子元素中所示的物件;這是一個將 Table
與 Select
構造組合在一起的“INSERT FROM SELECT”構造,它們各自獨立地影響構造的 SQL 字串生成。對於這個類,示例說明了它根本不參與快取:
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
雖然上述的 InsertFromSelect
也可能生成由 Table
和 Select
元件組成的快取鍵,但目前該 API 並不完全公開。但是,對於“INSERT FROM SELECT”構造,它只用於特定操作,快取並不像前面的示例那樣關鍵。
對於在相對孤立並且通常是獨立的物件,比如自定義 DML 構造,比如“INSERT FROM SELECT”,快取通常不太關鍵,因為對於這種構造物的缺乏快取只會對該特定操作產生區域性影響。
更多示例
“UTC 時間戳”函式
一個類似於“CURRENT_TIMESTAMP”的函式,但應用適當的轉換,使時間處於 UTC 時間。時間戳最好儲存在關聯式資料庫中作為 UTC 時間,不帶時區。UTC 時間是為了在夏令時結束時,資料庫不會認為時間倒退一小時,不帶時區是因為時區就像字元編碼一樣——最好只在應用程式的端點應用(即在使用者輸入時轉換為 UTC 時間,在顯示時重新應用所需的時區)。
對於 PostgreSQL 和 Microsoft SQL Server:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
示例用法:
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
metadata = MetaData()
event = Table("event", metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
)
“GREATEST”函式
“GREATEST”函式被賦予任意數量的引數,並返回具有最高值的引數——它等同於 Python 的max
函式。一個 SQL 標準版本與一個基於 CASE 的版本相對應,後者僅容納兩個引數:
from sqlalchemy.sql import expression, case
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
示例用法:
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
“false”表示式
渲染“false”常量表示式,在沒有“false”常量的平臺上呈現為“0”:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
def int_false(element, compiler, **kw):
return "0"
示例用法:
from sqlalchemy import select, union_all
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
)
“UTC 時間戳”函式
一個類似於“CURRENT_TIMESTAMP”的函式,但應用適當的轉換,使時間處於 UTC 時間。時間戳最好儲存在關聯式資料庫中作為 UTC 時間,不帶時區。UTC 時間是為了在夏令時結束時,資料庫不會認為時間倒退一小時,不帶時區是因為時區就像字元編碼一樣——最好只在應用程式的端點應用(即在使用者輸入時轉換為 UTC 時間,在顯示時重新應用所需的時區)。
對於 PostgreSQL 和 Microsoft SQL Server:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
示例用法:
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
metadata = MetaData()
event = Table("event", metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
)
“GREATEST”函式
“GREATEST”函式被賦予任意數量的引數,並返回具有最高值的引數——它等同於 Python 的max
函式。一個 SQL 標準版本與一個基於 CASE 的版本相對應,後者僅容納兩個引數:
from sqlalchemy.sql import expression, case
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
示例用法:
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
“false”表示式
渲染“false”常量表示式,在沒有“false”常量的平臺上呈現為“0”:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
def int_false(element, compiler, **kw):
return "0"
示例用法:
from sqlalchemy import select, union_all
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
)