normlite.engine.context¶
Provide key runtime abstraction for executing SQL statements.
The design of SQL statement execution separates responsibilities cleanly using the following key classes:
Class |
Responsibility |
|---|---|
Describes what to execute (e.g. |
|
Translates the |
|
Orchestrates binding, compilation, and result setup. |
|
Owns the DBAPI connection and executes statements. |
|
Factory for |
Added in version 0.7.0: ExecutionContext orchestrates binding, compilation, and result setup.
Module Contents¶
- class normlite.engine.context.ExecutionStyle(*args, **kwds)[source]¶
Bases:
enum.EnumDefine the execution style for a context.
Added in version 0.8.0.
- EXECUTE¶
A single operation is executed.
It indicates cursor.execute() will be used.
Changed in version 0.9.0.
- EXECUTEMANY¶
Multiple operations are executed on a query result.
It indicates that cursor.execute() will be used. This execution style is used for DELETE/UPDATE statements where the execution loop is driven by the query results.
Changed in version 0.9.0.
- INSERTMANYVALUES¶
The same operation is executed multiple times with different parameters.
This execution style is used for INSERT statements that add multiple rows. The execution loop is driven by the parameters.
Added in version 0.9.0.
- class normlite.engine.context.ExecutionContext(engine: normlite.engine.base.Engine, connection: normlite.engine.base.Connection, cursor: normlite.notiondbapi.dbapi2.Cursor, compiled: normlite.sql.base.Compiled, distilled_params: normlite.engine.interfaces._CoreMultiExecuteParams | None = None, *, execution_options: Mapping[str, Any] | None = None)[source]¶
Orchestrate binding, compilation, and result setup.
This class manages the key activities for the execution of SQL statements. It binds dynamically the parameters at runtime prior to execution using the owned
normlite.sql.Compiledobject. After execution, it sets up thenormlite.cursor.CursorResultobject to be returned using the ownednormlite.notiondbapi.dbapi2.Cursor(which contains the result set of the executed statement).Changed in version 0.8.0:
_bind_params()now binds values to named arguments by looking up parameters recursively. This enables to support bind parameters for all DDL/DML constructs.See also
- normlite SQL compiler
normlite.sql.compilermodule Here you find examples illustrating the code emitted for various DDL/DML constructs.
Added in version 0.7.0:
_bind_params()expects that parameters have been provided for all columns. It raisesnormlite.exceptions.ArgumentErrorif this is not the case.- engine: normlite.engine.base.Engine¶
Engine which the connection is associated with.
Added in version 0.8.0.
- connection: normlite.engine.base.Connection¶
Connection associated with the engine.
- _cursor: normlite.notiondbapi.dbapi2.Cursor | None¶
The DBAPI cursor holding the result set of the executed statement if no pre-fetch/post-fetch is required.
See also
Added in version 0.8.0.
- compiled: normlite.sql.base.Compiled¶
The compiled statement.
Changed in version 0.8.0.
- compiled_dict: dict¶
The JSON object representing result of the compilation + parameter binding.
This attribute must be computed prior to executing the context.
Added in version 0.8.0.
Example:
# insert many values, note "payload" is a list containing each row to be added { "operation": { "endpoint": "pages", "request": "create", }, "payload" : [ { "parent": { "type": "database_id", "database_id": "59833787-2cf9-4fdf-8782-e53db20768a5", }, "properties": { "name": { "title": [ { "text": { "content": "Galileo Galilei" } } ] }, "is_active" : { "checkbox": True } } }, { "parent": { "type": "database_id", "database_id": "59833787-2cf9-4fdf-8782-e53db20768a5", }, "properties": { "name": { "title": [ { "text": { "content": "Isaac Newton" } } ] }, "is_active" : { "checkbox": False } } }, ] }
- invoked_stmt: normlite.sql.base.Executable | None¶
The
normlite.sql.base.Executablestatement object that was given in the first place.This should be structurally equivalent to
compiled.statement, but not necessarily the same object as in a caching scenario the compiled form will have been extracted from the cache.Added in version 0.8.0.
- distilled_params: normlite.engine.interfaces._CoreMultiExecuteParams¶
The normalized bind parameters containing the values to be bound into
compiled_dict.Added in version 0.8.0.
- execution_style: ExecutionStyle¶
The style of DBAPI cursor method that will be used to execute a statement.
Added in version 0.8.0.
- execution_options: normlite.engine.interfaces.ExecutionOptions¶
Execution options associated with the current statement execution.
Added in version 0.8.0.
- _result: normlite.engine.cursor.CursorResult | None¶
The cursor result of the operation(s) executed in this context.
Added in version 0.8.0.
- _rowcount: int | None¶
The rowcount returned by an INSERT/UPDATE/DELETE/SELECT statement.
Added in version 0.9.0.
- _returned_primary_keys_rows: list[tuple] | None¶
The list of primary keys returned by the last executed DML statement as row.
Added in version 0.9.0.
- bulk_operation: dict | None¶
The operation to be executed when
execution_styleisExecutionStyle.EXCUTEMANY.Added in version 0.9.0.
- bulk_parameters: list[dict] | None¶
The parameters set for the bulk operation when
execution_styleisExecutionStyle.EXCUTEMANY.Added in version 0.9.0.
- _result_cursor: normlite.notiondbapi.dbapi2.Cursor | None¶
The cursor used internally for prefetching/postfetching Notion pages in delete/update/insert.
Added in version 0.9.0.
- _staged_result_cursor: normlite.notiondbapi.dbapi2.Cursor | None¶
The cursor used internally to route results after pre-fetch/post-fetching.
Added in version 0.9.0.
- property cursor: normlite.notiondbapi.dbapi2.Cursor | None¶
Return the effective DBAPI cursor for this execution.
This property implements cursor routing, selecting the cursor that represents the final, user-visible outcome of the execution.
Design principle¶
The decision of which cursor to expose is made entirely upstream during the execution pipeline, specifically in the statement’s
_finalize_execution()phase. This property does not contain any conditional logic related to statement type (INSERT/UPDATE/DELETE), execution options, or returning behavior.Instead, it simply reflects the outcome of that decision:
If a post-processing step (e.g. bulk update, post-fetch, RETURNING)
has produced a new cursor, it will have been assigned to
_result_cursorand is returned here. - Otherwise, the original execution cursor (_cursor) is returned.Added in version 0.9.0.
- _get_exec_cursor() normlite.notiondbapi.dbapi2.Cursor[source]¶
Return the execution cursor to be used in the pipeline.
This method is a private API that only
normlite.engine.base.Connectionmay use. It hides the implementaion details related to which cursor shall be used to execute the DBAPI operation. The cursor is crucial because it holds the result set(s). Different cursors are created, depending on the statement being executed. ForEXECUTEandINSERTMANYVALUESstyle statements (e.g., SELECT or bulk inserts), the_cursoris used to execute the operation and to hold the corresponding result set. ForEXECUTEMANYstyle statements (e.g., DELETE/UPDATE/INSERT…RETURNING), the_staged_result_cursoris used to execute the operation and to hold the corresponding result set.Added in version 0.9.0.
- _determine_execution_style() ExecutionStyle[source]¶
- property parameters: dict | list[dict]¶
Return the DBAPI parameters for the related operation.
This attribute provides the DBAPI parameters as a dictionary with the following keys:
“path_params”: This stores the path parameters for the DBAPI operation.
“query_params”: This stores the query paramters for the DBAPI operation.
“payload”: This stores the payload for the DBAPI operation.
parametersis a materialized view based on the parameters calculations done inpre_exec(). It aggregates the computed attributespath_params,query_params, andpayloadinto the DBAPI parameters dictionary structure.See also
normlite.notion_sdk.client.AbstractNotionClientfor the client parameters API structure.Changed in version 0.9.0.
Added in version 0.8.0.
- pre_exec() None[source]¶
Perform value binding and type adaptation before execution.
- ..versionchanged: 0.9.0
In this version, binding supports bulk inserts with multi-parameters.
Changed in version 0.8.0: In this version, binding has been extended to support the override case (user-provided parameters in the execute call). Execution options resolution is also supported now.
- post_exec() None[source]¶
Perform row counting preservation after execution.
Changed in version 0.9.0.
- _resolve_parameters(overrides: normlite.engine.interfaces._CoreMultiExecuteParams) Sequence[Mapping[str, normlite.sql.elements.BindParameter]][source]¶
Resolve binding parameters using the values passed as normalized parameters in the constructor.
Supports both single and multi-parameter execution.
Added in version 0.8.0.
- _build_overrides_sets() list[Mapping[str, Any]][source]¶
Build the list of parameter dictionaries used for execution.
Returns a list of dictionaries, one per execution (even for single execution).
- _validate_insert_values(resolved_parameters: dict[str, normlite.sql.elements.BindParameter] | list[dict[str, normlite.sql.elements.BindParameter]])[source]¶
- _resolve_bindparam(bindparam: normlite.sql.elements.BindParameter) dict[source]¶
- setup_cursor_result() normlite.engine.cursor.CursorResult[source]¶
Finalize execution and materialize a
normlite.engine.cursor.CursorResult.This method represents the terminal step of the execution pipeline. It materializes a read-only façade (CursorResult) over the DBAPI cursor’s post-execution state and freezes the outcome of this execution.
Key design guarantees¶
Execution is frozen
Once this method is called, the execution outcome is considered final. No further mutation of the underlying cursor or execution context is permitted or expected.
Single-execution binding
The returned
CursorResultis bound to exactly one execution of one compiled statement. EachExecutionContextmay produce at most one result object.Materialized result façade
The
CursorResultacts as a read-only façade over the cursor’s final state. It exposes rows, metadata, and identity information derived from the cursor without copying or re-buffering data.Identity preservation
- At the time this method is called:
execution has fully completed
all row and object identities (e.g. Notion object IDs / lastrowid)
have been resolved and preserved - the cursor reflects the final, stable execution state
Source of truth
The execution context and its cursor remain the authoritative source of execution data. The result object does not mutate or re-interpret execution state.
Lifecycle and usage¶
This method is not intended for direct invocation by users. It is called internally by the connection execution pipeline once statement execution has completed successfully.
Repeated calls to this method return the same
CursorResultinstance, ensuring idempotence and enforcing one-time result creation.Note
The underlying DBAPI cursor must not be mutated after this method has been invoked.
Result consumption (iteration, scalar access, identity inspection)
may occur lazily, but the execution itself is fully complete.
Changed in version 0.8.0: This version formalizes structural membership and API contract.
- returns:
- A read-only result object representing the finalized outcome of
this execution.
- rtype:
CursorResult
- get_rowcount() int | None[source]¶
Return the DBAPI
cursor.rowcountvalue, or in some cases an interpreted value.See
normlite.engine.cursor.CursorResult.rowcountfor details on this.Added in version 0.9.0.
- normlite SQL compiler