Skip to main content

Fast SQL normalization and fingerprinting engine with Python bindings

Project description

SQLFP

Normalize and fingerprint SQL queries in Python — typically 16–20× faster than sqlglot on realistic workloads.

CI PyPI Python License

pip install sqlfp

SQLFP is a fast Python library that normalizes SQL queries and generates stable fingerprints.

It parses a SQL string, canonicalizes it (removing literals and normalizing structure), and returns:

  • a normalized SQL string
  • a stable hash suitable for grouping queries
  • extracted parameters

Ideal for observability, monitoring, and performance tooling.

SQLFP is not a general-purpose SQL transformation library.


Quick Example

import sqlfp

result = sqlfp.normalize(
    sql="SELECT * FROM users WHERE id = 123",
    dialect="mysql",
    placeholder="<val>",
)

print(result.hash)
# 3886cc37e387f27530d0506c3ba2305bb8d75dbb17ce68036e92567b1791c639

print(result.normalized)
# SELECT * FROM users WHERE id = <val>

print(result.original)
# SELECT * FROM users WHERE id = 123

print(result.params)
# ['123']

Installation

pip install sqlfp

Prebuilt wheels are provided.
No Rust toolchain is required.

Requirements: Python ≥ 3.9


Why SQLFP?

SQLFP is implemented in Rust (via sqlparser-rs + PyO3) and exposed as a minimal Python extension.

Compared to pure-Python SQL parsers, it focuses specifically on deterministic fingerprinting and performance.

Typical characteristics:

  • 16×–20× faster than sqlglot
  • Deterministic normalization
  • Multi-dialect support
  • Designed for query fingerprinting workloads

SQLFP focuses on one problem: producing stable query fingerprints as fast and predictably as possible.


Performance

Benchmarks were executed in release mode over 100 rounds using realistic queries.

SQLFP is typically 16×–20× faster than sqlglot depending on dialect and query complexity.

Workload sqlfp sqlglot
PostgreSQL queries baseline ~16× slower
MySQL queries baseline ~20× slower
Oracle queries baseline ~21× slower
ORM-style long queries baseline ~20× slower

Benchmark scripts are available in bench/. Results may vary depending on workload and hardware.


API

normalize()

normalize(
    sql: str,
    dialect: str = "generic",
    placeholder: str = "?"
) -> NormalizeResult

Returns a NormalizeResult object:

  • hash: str
  • normalized: str
  • original: str
  • params: list[str]

Supported Dialects

  • PostgreSQL
  • MySQL
  • SQLite
  • Oracle
  • MSSQL
  • ANSI

What SQLFP Normalizes

SQLFP performs:

  • Literal replacement (123, 'abc', etc. → placeholder)
  • Whitespace normalization
  • Case normalization
  • Removal of redundant parentheses
  • Canonical formatting (stable rendering)
  • Stable hashing (SHA-256)

Example:

SELECT id FROM users WHERE id = 42;
SELECT id FROM users WHERE id = 999;

Both normalize to:

SELECT id FROM users WHERE id = ?

They therefore share the same fingerprint.


What SQLFP Does NOT Do

  • Does not rewrite queries semantically
  • Does not optimize SQL
  • Does not execute queries
  • Does not guarantee cross-dialect equivalence

SQLFP focuses strictly on structural fingerprinting.


Use Cases

  • Database performance monitoring
  • Query aggregation dashboards
  • Slow query analysis
  • Log deduplication
  • Observability pipelines

Architecture

SQLFP uses a Rust core for performance and deterministic parsing, exposed through a minimal Python API.

Users do not need Rust installed.

Technologies used:

  • Rust core
  • sqlparser-rs
  • PyO3 bindings
  • Built with maturin

Project Status

SQLFP is currently in beta.

APIs may evolve before version 1.0.


Stability Guarantees

  • Fingerprints are stable within a given major version.
  • Any normalization change will trigger a major version bump.

Version

import sqlfp
print(sqlfp.__version__)

Contributing

Issues and pull requests are welcome.

Please:

  • open an issue before large changes
  • run tests before submitting
  • keep API stability in mind

Security

Please report vulnerabilities to:

opensource@iwod.com

Do not disclose vulnerabilities publicly before a fix is available.


License

MIT


Development

Development dependencies are pinned in requirements.lock to ensure reproducible local environments.

They are not required to use sqlfp as a library.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sqlfp-0.1.4-cp38-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.8+Windows x86-64

sqlfp-0.1.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

sqlfp-0.1.4-cp38-abi3-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file sqlfp-0.1.4-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: sqlfp-0.1.4-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sqlfp-0.1.4-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 33e7ee2f3190f4c6eba7108fc6afc1f5e6450b6d690a591220e3033d12d7126e
MD5 293b6242ecfe5d38b4e9f879dbc728ee
BLAKE2b-256 bfbef30ca6affc878e7d5b99254e416916d75a9eaff249ec3e110d2e529a56eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlfp-0.1.4-cp38-abi3-win_amd64.whl:

Publisher: release.yml on mstute/sqlfp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sqlfp-0.1.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sqlfp-0.1.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5cc3b7f796767fe2ac19e33b7969b87a5e281630fbfe0354a3a53821e0710fd4
MD5 0c7cad9eda0e188bbbf430e5f1cef1c9
BLAKE2b-256 75f15a8fdc9445df155ffc9ae88d6e3e4899f3290e8c8c227cbbfe4274b5fbbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlfp-0.1.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on mstute/sqlfp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sqlfp-0.1.4-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: sqlfp-0.1.4-cp38-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.8+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sqlfp-0.1.4-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 548aa5574ae286bfd2887dc0c18a5915ccef9234a1bbeef3dc9bacd2305a729a
MD5 7cc6f0c6c5ef0fc1d97937357659529c
BLAKE2b-256 5cb19d531f8d0fd1390c0acb970f32abfb539452ea3f6553b97c4e06773e5051

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlfp-0.1.4-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on mstute/sqlfp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page