# Cursors (executing SQL)

A cursor encapsulates a SQL query and returning results. You only need an explicit cursor if you want more information or control over execution. Using `Connection.execute()` or `Connection.executemany()` will automatically obtain a cursor behind the scenes.

If you need a cursor you should call `cursor()` on your database:

    db = apsw.Connection("databasefilename")
    cursor = db.cursor()

The example shows how to execute SQL and how to provide values used in queries (bindings).

Cursors are cheap. Use as many as you need. Behind the scenes a `Cursor` maps to a SQLite statement. APSW maintains a cache so that the mapping is very fast, and the SQLite objects are reused when possible.

Note

Cursors on the same Connection are not isolated from each other. Anything done on one cursor is immediately visible to all other Cursors on the same connection. This still applies if you start transactions. Connections are isolated from each other with cursors on other connections not seeing changes until they are committed.

See also

- SQLite transactions

- Atomic commit

- Benchmarking

## Cursor class

class apsw.Cursor(connection: Connection)

  Use `Connection.cursor()` to make a new cursor.

Cursor.__aiter__() → Self

  Async only

  AsyncCursors are async iterators

Cursor.__anext__() → Any

  Async only

  Cursors are iterators

Cursor.__iter__(self: Cursor) → Cursor

  Sync only

  Cursors are iterators

Cursor.__next__() → Any

  Sync only

  Cursors are iterators

Cursor.aclose(force: bool = False) → None

  Close

  Async version of `close()`

Cursor.bindings_count: int

  Value

  How many bindings are in the statement. The `?` form results in the largest number. For example you could do `SELECT ?123`` in which case the count will be `123`.

  Calls: sqlite3_bind_parameter_count

Cursor.bindings_names: tuple[str | None]

  Sync / Async

  A tuple of the name of each bind parameter, or None for no name. The leading marker (`?:@$`) is omitted

  Note

  SQLite parameter numbering starts at `1`, while Python indexing starts at `0`.

  Calls: sqlite3_bind_parameter_name

Cursor.close(force: bool = False) → None

  Close

  It is very unlikely you will need to call this method. Cursors are automatically garbage collected and when there are none left will allow the connection to be garbage collected if it has no other references.

  It is safe to call the method multiple times.

  A cursor is open if there are remaining statements to execute (if your query included multiple statements), or if you called `executemany()` and not all of the sequence of bindings have been used yet.

  Parameters:

    force – If False then you will get exceptions if there is remaining work to do be in the Cursor such as more statements to execute, more data from the executemany binding sequence etc. If force is True then all remaining work and state information will be silently discarded.

Cursor.connection: Connection

  Value

  `Connection` this cursor is using

Cursor.convert_binding: ConvertBinding | None

  Value

  Called with the `Cursor`, parameter number, and value when an unsuppported type is used in a binding. Note that parameter numbers start at 1.

  If set to `None` then conversion is disabled for this cursor.

  See also

  - `bindings_count`

  - `bindings_names`

Cursor.convert_jsonb: ConvertJSONB | None

  Value

  Called with the `Cursor`, column number, and bytes value when a blob value is valid JSONB. The callback can `decode the` or return the bytes as is.

  If set to `None` then conversion is disabled for this cursor.

  See also

  You can consult the description to get further confirmation if the value is intended to be JSONB.

  - `Cursor.description_full`

  - `Cursor.description`

Cursor.description: tuple[tuple[str, str, None, None, None, None, None], ...]

  Sync / Async

  Based on the DB-API cursor property, this returns the same as `get_description()` but with 5 Nones appended because SQLite does not have the information.

Cursor.description_full: tuple[tuple[str, str, str, str, str], ...]

  Sync / Async

Only present if SQLITE_ENABLE_COLUMN_METADATA was defined at compile time.

Returns all information about the query result columns. In addition to the name and declared type, you also get the database name, table name, and origin name.

Calls:

  - sqlite3_column_name

  - sqlite3_column_decltype

  - sqlite3_column_database_name

  - sqlite3_column_table_name

  - sqlite3_column_origin_name

Cursor.exec_trace: ExecTracer | None

  Value

  Called with the cursor, statement and bindings for each `execute()` or `executemany()` on this cursor.

  If callable is None then execution tracing is disabled for the cursor..

  See also

  - Tracing

  - Execution Tracer

  - `Connection.exec_trace`

Cursor.execute(statements: str, bindings: Bindings | None = None, *, can_cache: bool = True, prepare_flags: int = 0, explain: int = -1) → Cursor

  Sync / Async

  Executes the statements using the supplied bindings. Execution returns when the first row is available or all statements have completed.

  Parameters:

    - statements – One or more SQL statements such as `select * from books` or `begin; insert into books ...; select last_insert_rowid(); end`.

    - bindings – If supplied should either be a sequence or a dictionary. Each item must be one of the supported types, `zeroblob`, or a wrapped Python object

    - can_cache – If False then the statement cache will not be used to find an already prepared query, nor will it be placed in the cache after execution

    - prepare_flags – flags passed to sqlite_prepare_v3

    - explain – If 0 or greater then the statement is passed to sqlite3_stmt_explain where you can force it to not be an explain, or force explain or explain query plan.

  Raises:

    - TypeError – The bindings supplied were neither a dict nor a sequence

    - BindingsError – You supplied too many or too few bindings for the statements

    - IncompleteExecutionError – There are remaining unexecuted queries from your last execute

  See also

  - Example showing how to use bindings

  - Execution model

  Calls:

    - sqlite3_prepare_v3

    - sqlite3_step

    - sqlite3_bind_int64

    - sqlite3_bind_null

    - sqlite3_bind_text64

    - sqlite3_bind_double

    - sqlite3_bind_blob64

    - sqlite3_bind_zeroblob64

    - sqlite3_stmt_explain

Cursor.executemany(statements: str, sequenceofbindings: Iterable[Bindings], *, can_cache: bool = True, prepare_flags: int = 0, explain: int = -1) → Cursor

  Sync / Async

  This method is for when you want to execute the same statements over a sequence of bindings. Conceptually it does this:

      for binding in sequenceofbindings:
          cursor.execute(statements, binding)

  The return is the cursor itself which acts as an iterator. Your statements can return data. See `execute()` for more information, and the example.

Cursor.expanded_sql: str

  Sync / Async

  The SQL text with bound parameters expanded. For example:

      execute("select ?, ?", (3, "three"))

  would return:

      select 3, 'three'

  Note that while SQLite supports nulls in strings, their implementation of sqlite3_expanded_sql stops at the first null.

  You will get `MemoryError` if SQLite ran out of memory, or if the expanded string would exceed SQLITE_LIMIT_LENGTH.

  Calls: sqlite3_expanded_sql

Cursor.fetchall() → list[SQLiteValues]

  Sync / Async

  Returns all remaining result rows as a list. This method is defined in DBAPI. See `get()` which does the same thing, but with the least amount of structure to unpack.

Cursor.fetchone() → Any | None

  Sync / Async

  Returns the next row of data or None if there are no more rows.

Cursor.get: Any

  Sync / Async

  Like `fetchall()` but returns the data with the least amount of structure possible.

  Some examples
  Query | Result
  --- | ---
  select 3 | 3
  select 3,4 | (3, 4)
  select 3; select 4 | [3, 4]
  select 3,4; select 4,5 | [(3, 4), (4, 5)]
  select 3,4; select 5 | [(3, 4), 5]

  Row tracers are not called when using this method.

Cursor.get_connection() → Connection

  Value

  Returns the `connection` this cursor is part of

Cursor.get_description() → tuple[tuple[str, str], ...]

  Sync / Async

  If you are trying to get information about a table or view, then pragma table_info is better. If you want to know up front what columns and other details a query does then `apsw.ext.query_info()` is useful.

  Returns a tuple describing each column in the result row. The return is identical for every row of the results.

  The information about each column is a tuple of `(column_name, declared_column_type)`. The type is what was declared in the `CREATE TABLE` statement - the value returned in the row will be whatever type you put in for that row and column.

  See the query_info example.

  Calls:

    - sqlite3_column_name

    - sqlite3_column_decltype

Cursor.get_exec_trace() → ExecTracer | None

  Value

  Returns the currently installed `execution tracer`

  See also

  - Tracing

Cursor.get_row_trace() → RowTracer | None

  Value

  Returns the currently installed (via `set_row_trace()`) row tracer.

  See also

  - Tracing

Cursor.has_vdbe: bool

  Value

  `True` if the SQL does anything. Comments have nothing to evaluate, and so are `False`.

Cursor.is_explain: int

  Value

  Returns 0 if executing a normal query, 1 if it is an EXPLAIN query, and 2 if an EXPLAIN QUERY PLAN query.

  Calls: sqlite3_stmt_isexplain

Cursor.is_readonly: bool

  Value

  Returns True if the current query does not change the database.

  Note that called functions, virtual tables etc could make changes though.

  Calls: sqlite3_stmt_readonly

Cursor.row_trace: RowTracer | None

  Value

  Called with cursor and row being returned. You can change the data that is returned or cause the row to be skipped altogether.

  If `None` then row tracing is disabled for this cursor.

  See also

  - Tracing

  - Row Tracer

  - `Connection.row_trace`

Cursor.set_exec_trace(callable: ExecTracer | None) → None

  Value

  Sets the `execution tracer`

Cursor.set_row_trace(callable: RowTracer | None) → None

  Value

  Sets the `row tracer`. If `None` then row tracing is disabled for this cursor.

Cursor.sql: str

  Sync / Async

  The SQL being executed

  Calls: sqlite3_sql