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

Uploaded CPython 3.8+Windows x86-64

sqlfp-0.1.3-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.3-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.3-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: sqlfp-0.1.3-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.3-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 87df59b349e3a5ecbc96464dd7858315267de5a0555037d5cb56bf9528715061
MD5 cbe19f2ea10b8e6e25ec1f7549543db2
BLAKE2b-256 03b0d15892a88df82c6a5c6e361cdbaa1bb65bdecd23368638fb7a37e25000c3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for sqlfp-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c4d56dad87204d5c0780400cf683824b68894bac1a0ab8eaee2ca0b9ee1e3945
MD5 060aeccca01c3a0d4e48feb7778c8399
BLAKE2b-256 7a076e0294301a5e166e2b90e753599b9e02ad62b7997197dfffc5c4ffbf71f0

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: sqlfp-0.1.3-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.3-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 552d4742c9a110b439c20b7ba4f953b98694d362ddcf375a914f2a38e1a8b515
MD5 db6eb13ac739c8736c21da4a9ead42d7
BLAKE2b-256 d5473c5eb6bae4c295931d815a798088df740300ca9f26074e91f780e85d1df2

See more details on using hashes here.

Provenance

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