APSW

repository·master·Indexed 19 days ago

https://github.com/rogerbinns/apsw

A high-performance Python wrapper for SQLite that exposes the complete SQLite C API. It provides advanced features beyond the standard sqlite3 module, including asynchronous support for asyncio, Trio, and AnyIO, a set of connection best practices (WAL mode, foreign keys, busy timeouts), and extensions for dataclass row factories, SQL execution tracing, and custom type conversion.

Tokens
41.6K
Snippets
134
Records
230
Agent score
67%

What's inside apsw

  1. Overview of APSW Full Text Search (FTS5) capabilities

    master

    APSW provides comprehensive access to SQLite's fts5 extension. It allows developers to perform high-performance text searches by indexing tokens (typically words) and their locations (rowid, column, and token number).

    Key features include:

    • Pythonic Interface: Use apsw.fts5.Table for managing FTS5 tables, including automatic handling of SQL quoting, triggers, and options via .create().
    • Advanced Tokenization: Access to specialized tokenizers like UnicodeWordsTokenizer, RegexTokenizer, HTMLTokenizer, and JSONTokenizer. You can also register custom tokenizers using apsw.Connection.register_fts5_tokenizer.
    • Search Enhancements: Support for query suggestions (Table.query_suggest), finding statistically similar rows (Table.more_like), and retrieving significant content (Table.key_tokens).
    • Ranking & Relevance: Ability to configure ranking functions via Table.config_rank or on a per-query basis to score matches based on rarity and density.
    • Unicode Support: Integration with apsw.unicode for advanced text processing (grapheme clusters, case folding, accent removal) to ensure high-quality text ingestion and display.
  2. Overview of APSW

    master

    APSW (Another Python SQLite Wrapper) is a Python wrapper for the SQLite embedded relational database engine. Unlike the standard sqlite3 module, APSW provides direct access to the complete SQLite C API, allowing developers to use advanced SQLite features directly from Python. It supports CPython 3.10 and onwards.

    Key features supported by APSW include:

    • Full Text Search
    • Session extension
    • Virtual Tables
    • VFS (Virtual File System)
    • JSON support
    • CArray
    • Full support for all Python async frameworks
    • Both synchronous and asynchronous code execution
  3. Use the APSW shell for SQLite interaction

    master

    The APSW shell is a command-line interface for interacting with SQLite, performing administration, and executing SQL. It is modeled after the standard SQLite shell but includes improvements like colorized output, tab completion, and the ability to switch between all open APSW connections. It also allows for programmatic invocation and provides a Python REPL via the .py command.

    Key Features:

    • Colorized Output: Enabled by default (on modern Windows) or via the NO_COLOR environment variable.
    • Tab Completion: Available for commands and SQL.
    • Connection Management: You can switch between multiple open APSW connections.
    • Python Integration: Run Python code or enter a REPL directly within the shell.
    • Enhanced Dumps: Provides nicer text dump output including metadata like user_version.
    python3 -m apsw [OPTIONS] FILENAME [SQL|CMD] [SQL|CMD]...
  4. Use multi-threading with APSW

    master

    APSW supports multi-threaded programs by releasing the Python Global Interpreter Lock (GIL) during long-running SQLite operations like preparing and executing statements.

    Key threading rules:

    • Concurrency: You do not get concurrency by using multiple threads on a single Connection. To achieve true concurrency, use multiple Connection objects.
    • Mutexes: SQLite uses a mutex to ensure only one thread executes at a time. If a thread attempts an operation while another is busy, Cursor.execute, Cursor.executemany, or cursor iteration will wait up to 1/3 of a second for the mutex before raising a ThreadingViolationError.
    • Thread Safety: APSW checks that SQLite was compiled in threadsafe mode (the default).
  5. Handling Blobs and Date/Time types

    master

    SQLite does not have native date or time types; dates and times are typically stored as strings or Julian days (floating point numbers). Use SQLite's built-in functions for date/time manipulation.

    For BLOB data, use any type that implements the collections.abc.Buffer interface, such as bytes.

  6. How APSW differs from the Python DBAPI (PEP 249)

    master

    APSW does not follow the standard Python DBAPI (PEP 249) exactly. Key differences include:

    • No connect() method: Use the apsw.Connection constructor directly.
    • No commit() or rollback() methods: Manage transactions manually using SQL commands (BEGIN, COMMIT, ROLLBACK) or use the Connection object as a context manager (with Connection(...) as conn:) for automatic transaction control and support for nested transactions (savepoints).
    • No rowcount: SQLite returns results one row at a time, so a pre-calculated row count is not provided.
    • No fetchone() or fetchmany(): To retrieve rows, use the Cursor as an iterator or use Cursor.fetchall() to get all remaining results.
    • No callproc(): SQLite does not support stored procedures.
    • Exception handling: DBAPI exceptions are not used. Instead, APSW uses specific exceptions corresponding to SQLite error codes, which are located on the apsw module rather than on the Connection object.
  7. Manage contextvars in async mode

    master

    APSW propagates contextvars from the event loop to the database worker thread and back. This allows callbacks to access context-specific values.

    Important Notes:

    • Memory Management: Always use contextvars.ContextVar.reset to avoid increasing memory consumption. APSW provides apsw.aio.contextvar_set as a convenient way to handle this.
    • Scope: Setting a variable is not visible to code earlier in the call chain. To allow all code in a chain to see and modify values, use a mutable object like a dict as the value.
  8. Understanding exception chaining in APSW

    master

    When multiple errors occur within a single SQLite control flow, APSW uses Python's exception chaining (PEP 3134).

    For example, if an error occurs in a VFS (Virtual File System) operation, SQLite might attempt error recovery. If your recovery code also raises an exception, both exceptions will be chained. Python's traceback will display the full context of all exceptions involved in the sequence.

  9. Understand the speedtest test types

    master

    When running apsw.speedtest, you can select specific test types using the --tests flag. These tests measure different aspects of the API and engine overhead:

    • bigstmt: Supplies SQL as a single large string containing multiple statements (e.g., a database dump). APSW handles this via cursor.execute(), whereas sqlite3 requires cursor.executescript(). This simulates restoring a database.
    • statements: Runs SQL queries using parameter bindings (e.g., cursor.execute("insert into table foo values(?)", (i,))). This test frequently hits the statement cache.
    • statements_nobindings: Runs SQL queries without bindings (e.g., cursor.execute("insert into table foo values(0)")). This test avoids statement cache hits and measures the overhead of the statement cache itself.
    # Example: View details of what the tests do without running them
    python3 -m apsw.speedtest --tests-detail
  10. Handle exceptions in user-defined functions

    master

    When a Python function registered as a SQLite scalar or aggregate function raises an exception, APSW correctly propagates the error and converts it into a SQLite error. This allows the traceback to show the actual line in your Python code where the error occurred. In contrast, sqlite3 often swallows these exceptions, making debugging difficult.

    def badfunc(t):
        return 1/0
    
    import apsw
    con = apsw.Connection(":memory:")
    con.create_scalar_function("badfunc", badfunc, 1)
    cur = con.cursor()
    cur.execute("select badfunc(3)")
  11. How APSW handles exceptions and SQLite error codes

    master

    APSW bridges the gap between Python's exception-based error handling and SQLite's integer error code system.

    • Python to SQLite: If an exception is raised in Python code that is being called by SQLite (such as a custom function or VFS implementation), APSW ensures that the exception is present when control returns to Python, and SQLite is notified that an error occurred.
    • SQLite to Python: APSW maps SQLite's integer error codes to appropriate Python exceptions.