Skip to main content

Python DB-API paramstyle converter

Problem

The DB-API is one of the greatest feature in our python-world. But paramstyle...

module paramstyle
sqlite3 qmark
mysql-connector-python pyformat
mysqlclient format
mariadb qmark
psycopg2 pyformat
psycopg pyformat
py-postgresql pyformat
pyodbc qmark
pymssql pyformat
python-oracledb named
duckdb qmark
firebird-driver qmark
pydrda format
pymonetdb pyformat
pyhive.hive/presto pyformat
  • qmark: ?, ?
  • pyformat: %(name)s, %(arg)s
  • format: %s, %s
  • named: :name, :arg
  • numeric: :1, :2

Install

  • pip install pstyle

test with CLI

# pstyle --help
Usage: pstyle [OPTIONS] COMMAND [ARGS]...

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

Commands:
  convert  convert SQL and params with specified paramstyle
# pstyle convert --args hello --args world --from-style qmark --to-style format "select * from tbl1 where `key`=? and `value`=?"
op: SELECT * FROM tbl1 WHERE `key`=%s AND `value`=%s
args: ('hello', 'world')
# pstyle convert --args world --args hello --from-style numeric --to-style qmark "select * from tbl1 where `key`=:2 and `value`=:1"
op: SELECT * FROM tbl1 WHERE `key`=? AND `value`=?
args: ('hello', 'world')

using docker

# docker run --rm ghcr.io/wtnb75/pstyle convert --help
Usage: pstyle convert [OPTIONS] OPERATION

  convert SQL and params with specified paramstyle

Options:
  --verbose / --quiet
  --from-style [named|pyformat|qmark|numeric|format|auto]
  --to-style [named|pyformat|qmark|numeric|format]
  --args TEXT
  --kwargs TEXT                   json
  --normalize / --original        [default: normalize]
  --help                          Show this message and exit.

convert from str, args

import sqlite3
from pstyle.convert import Pstyle

db = sqlite3.connect(":memory:")
print("paramstyle:", sqlite3.paramstyle)  # qmark
cursor = db.cursor()
cursor.execute(
    *Pstyle.convert(
        "numeric",
        sqlite3.paramstyle,
        "select * from tbl1 where id=:2 and val=:1",
        ("val1", 1),
    )
)
# -> cursor.execute("SELECT * FROM tbl1 WHERE id=? AND val=?", (1, "val1"))

wrap DB connection instance

import sqlite3
from pstyle.wrapper import DBWrapper

db = sqlite3.connect(":memory:")
print("paramstyle:", sqlite3.paramstyle)  # qmark
db2 = DBWrapper(db, sqlite3.paramstyle, "numeric")
cursor = db2.cursor()
cursor.execute("select * from tbl1 where id=:2 and val=:1", ("val1", 1))
# -> SELECT * FROM tbl1 WHERE id=? AND val=?, (1, "val1")
result = cursor.fetchone()

wrap cursor instance

import sqlite3
from pstyle.wrapper import CursorWrapper

db = sqlite3.connect(":memory:")
print("paramstyle:", sqlite3.paramstyle)  # qmark
cursor = CursorWrapper(db.cursor(), sqlite3.paramstyle, "numeric")
cursor.execute("select * from tbl1 where id=:2 and val=:1", ("val1", 1))
# -> SELECT * FROM tbl1 WHERE id=? AND val=?, (1, "val1")
result = cursor.fetchone()

try Python REPL with db connection

# pstyle try-db 'sqlite3://:memory:'
db(qmark): db.execute(...)
wrapped(auto): wrapped.execute(...)
Python 3.12.4 (main, Jun 20 2024, 00:32:08) [Clang 15.0.0 (clang-1500.3.9.4)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.21.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: wrapped.execute("create table tbl1 (id integer, val varchar)")
Out[1]: <sqlite3.Cursor at 0x10c519040>

In [2]: wrapped.execute("insert into tbl1 (id, val) values (%s, %s), (%s, %s)", (1, "val1", 2, "val2")).fetchall()
Out[2]: []

In [3]: wrapped.execute("select * from tbl1").fetchall()
Out[3]: [(1, 'val1'), (2, 'val2')]

In [4]: wrapped.execute("select * from tbl1 where id=:key1", dict(key1=1)).fetchall()
Out[4]: [(1, 'val1')]

In [5]: wrapped.execute("select * from tbl1 where id=:key1", dict(key1=2)).fetchall()
Out[5]: [(2, 'val2')]

Metadata

Release files for pstyle 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for pstyle 0.2.1
File Interpreter ABI Platform Actions
pstyle-0.2.1-py3-none-any.whl Python 3 none any Details for pstyle-0.2.1-py3-none-any.whl

Release files / pstyle-0.2.1-py3-none-any.whl

Download URL pstyle-0.2.1-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
77c8f1b158beecab6a180fea95b48b87acfc03b756563cffd090c50e922119c7
BLAKE2b-256 checksum
How to use checksums
48b03340733a36dc896edd8edbbb719169874240cd85a41648ad04c386f77ca3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for pstyle 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page