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 = "postgres",
    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 alpha.

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.2-cp38-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.8+Windows x86-64

sqlfp-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

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

sqlfp-0.1.2-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.2-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: sqlfp-0.1.2-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.2-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 15240b04eb538fe69ac1d6ba1b9aa67eaf9295eaff2038cc4e4b3d4f46b251f7
MD5 95809de1899070533cab1586df0061e3
BLAKE2b-256 922221fadea4cb2a137a283afbe095060b5c517b52abb3b72d17df99db65cf26

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlfp-0.1.2-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.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sqlfp-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bbb606b3090499c4326df6c39ee5e504a3f5e63c3107e8398c541e24ce1b6efc
MD5 74e130d689899b9133dbcc10202e2472
BLAKE2b-256 134ae203eb0fc145a2a2756c65f594f2087e0d8188158c1eee1d6de7d15c3e37

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlfp-0.1.2-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.2-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: sqlfp-0.1.2-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.2-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aeb19b718609bed3f44b14ded79d9f110f4baf6850ce1e9e7b80d74cffbdbd95
MD5 160c038352e1516341e6afa4c49c8ca8
BLAKE2b-256 a5e0b568a6dba80ce3f37b8cdc4c7ad36d59810d5d8d77204b2a2288c903a262

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlfp-0.1.2-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