Skip to content

pyxle-db 0.2.0

Choose a tag to compare

@shivamsn97 shivamsn97 released this 12 Jun 08:20
e6cc4b6

Changed (BREAKING)

  • Database.transaction() now yields a transaction whose methods are
    coroutines: await tx.execute(...), await tx.fetchone(...), etc.
    In 0.1 these calls were synchronous inside the async context manager.
  • Database.close() and Database.sync_transaction() are SQLite-only
    and raise UnsupportedOperationError on server backends. Use
    await db.aclose() and async with db.transaction() — both work on
    every backend.
  • Mapping (named) parameters are SQLite-only; portable SQL uses
    positional ? parameters.

Added

  • PostgreSQL backend via asyncpg (pip install 'pyxle-db[postgres]')
    and MySQL backend via asyncmy (pip install 'pyxle-db[mysql]').
    The base install remains SQLite-only with zero extra dependencies.

  • Database URLs: Database(...)/connect(...) accept
    sqlite:///..., postgresql://..., and mysql://... connection
    strings alongside the 0.1 bare SQLite path. DatabaseConfig and
    parse_database_url are exported for programmatic use.

  • Portable placeholders: qmark (?) SQL is translated per backend
    ($1 for PostgreSQL, %s for MySQL) with a literal-aware rewriter;
    ?? escapes a literal question mark for PostgreSQL JSON operators.

  • Backend-neutral Row result type (index + name access) and Dialect
    metadata, both exported from pyxle_db.

  • New error types: OperationalError (retryable connection/timeout
    family), ConfigurationError, and UnsupportedOperationError.
    Driver exceptions are translated on every backend — application code
    never handles sqlite3/asyncpg/asyncmy exceptions.

  • Datetimes come back timezone-aware UTC on every backend; naive values
    stored in the database are assumed UTC and tagged.

  • Plugin: new url setting that takes precedence over path, with
    env:VAR_NAME indirection so credentials stay out of the committed
    pyxle.config.json (startup raises ConfigurationError when the
    variable is unset). The plugin now also registers db.url, a
    password-redacted connection string for logging.

  • Migrations: backend-specific override files
    (0003-fulltext-index.postgresql.sql next to
    0003-fulltext-index.sql) for migrations that need per-dialect DDL.

  • DatabaseLike / TransactionLike protocols (pyxle_db.contract,
    exported at top level): the structural contract third-party database
    layers implement to back plugins like pyxle-auth. Database is the
    reference implementation; both protocols are runtime_checkable and
    the conformance is regression-tested.

Fixed

  • Plugin shutdown awaits Database.aclose(), releasing async pools
    cleanly instead of relying on the SQLite-only synchronous close.
  • Aware datetimes now bind on every backend (found by the live-server
    suites). PostgreSQL and MySQL pass parameters through
    utc_naive_params(): an aware datetime is converted to UTC and bound
    naive, matching the SQLite adapter and the read-side "naive equals
    UTC" rule. Previously asyncpg rejected aware datetimes for TIMESTAMP
    columns and asyncmy silently serialised the foreign wall clock.
  • The MySQL pool pins each session to UTC (SET time_zone = '+00:00'),
    so TIMESTAMP columns and NOW() are no longer shifted through the
    server's system time zone on read.
  • The mysql extra now includes cryptography: MySQL 8's default
    caching_sha2_password auth fails at connect without it.
  • Dependency floor corrected to pyxle-framework>=0.4.0 — the
    pyxle.plugins API first shipped in 0.4.0, so older resolutions
    could not import.

Install: pip install pyxle-db · extras: [postgres], [mysql]
Docs: https://pyxle.dev/docs/plugins/pyxle-db