Skip to main content

SQL Server stored procedure introspection and Pydantic model generator

Project description

Singularity

SQL Server → Pydantic v2. Automatically.

CI Python Ruff

SingularitySQL bridges the gap between SQL Server and Python. Connect to your database, point at a stored procedure, and get a Pydantic v2 model — as a runtime class or a .py file you can commit.

singularity generate --config config.toml
from singularity import SQLServerIntrospector, generate_model

introspector = SQLServerIntrospector("DRIVER={ODBC Driver 17};SERVER=...;DATABASE=...")
meta = introspector.introspect("usp_GetOrders")
model = generate_model(meta, mode="dynamic")
# <class 'pydantic.main.UspGetOrders'>

Why SingularitySQL?

The problem: You have dozens of complex stored procedures in SQL Server. Calling them from Python means manually writing Pydantic models for every parameter and result set. One typo, and you get a runtime error.

The solution: SingularitySQL reads SQL Server's system catalog (sys.parameters, sp_describe_first_result_set) and generates the models for you. Zero manual mapping.

Approach Lines of code Maintainable Type-safe
Manual Pydantic models 100s–1000s ⚠️ (manual)
Raw dicts / tuples Fewer
SingularitySQL Zero

Features

  • 🔌 Auto-connect — pyodbc connection with @@VERSION detection
  • 🧠 Version-aware — Modern (2016+), Legacy (2008–2014), and Azure SQL strategies
  • 📦 Two output modes:
    • "dynamic"create_model() at runtime, usable immediately
    • "source".py files you can commit and review
  • 🏷️ Full type mappingINTint, VARCHARstr, DATETIMEdatetime, BITbool, etc.
  • 🎨 Configurable naming — snake_case, camelCase, PascalCase for field names
  • 🗂️ File naming templates{schema}_{sp_name}.py, {database}_{sp_name}.py, etc.
  • 🛡️ Nullable awarenessOptional[T] for nullable columns
  • UV-first — fast dependency management

Installation

uv add singularitysql
# or
pip install singularitysql

Windows users: scripts go into .venv/Scripts/, not the global PATH. Activate the virtual environment first, or use uv run singularity ... to avoid command not found errors.

Prerequisite: ODBC Driver for SQL Server (17 or 18).

Quick Start

1. Create a config file

# config.toml
[connection]
server = "localhost"
database = "AdventureWorks"
driver = "ODBC Driver 18 for SQL Server"
trusted_connection = true

[sp_selection]
pattern = "usp_%"

[output]
directory = "generated_models"
mode = "source"
file_naming = "{schema}_{sp_name}.py"
naming_convention = "snake_case"

2. Generate models

singularity generate --config config.toml
Connected. Detected version: modern
  Introspecting usp_GetOrders... → generated_models/dbo_usp_GetOrders.py
  Introspecting usp_GetCustomers... → generated_models/dbo_usp_GetCustomers.py

Done. 2 succeeded, 0 failed.

3. Use the generated models

from generated_models.dbo_usp_GetOrders import UspGetOrders

order = UspGetOrders(id=1, customer_name="Acme Corp", total=99.99)

Python API

from singularity import SQLServerIntrospector, generate_model

# Connect and introspect
introspector = SQLServerIntrospector(conn_str)
introspector.connect()
version = introspector.detect_version()  # ServerVersion.MODERN
metadata = introspector.introspect("usp_GetOrders")

# Runtime model
DynamicModel = generate_model(metadata, mode="dynamic")
instance = DynamicModel(id=1, customer_name="Acme")

# Source code string
source_code = generate_model(metadata, mode="source")
with open("models/usp_GetOrders.py", "w") as f:
    f.write(source_code)

Configuration Reference

[connection]

Field Required Default Description
server Server hostname or IP
database Database name
driver ODBC Driver 18 for SQL Server ODBC driver name
trusted_connection true Use Windows auth
username SQL auth username
password SQL auth password

[sp_selection]

Field Required Description
procedures Explicit list of SP names
pattern Wildcard pattern (e.g. usp_%)

At least one of procedures or pattern must be specified.

[output]

Field Required Default Description
directory . Output directory
mode source source or dynamic
file_naming {sp_name}.py Template with {schema}, {database}, {sp_name}
naming_convention snake_case snake_case, camelCase, or PascalCase

Supported SQL Server Versions

Version Strategy Parameter introspection Result set metadata
2016+ Modern sys.parameters sp_describe_first_result_set
2008–2014 Legacy sys.parameters sp_describe_first_result_set + sys.columns fallback
Azure SQL Azure sys.parameters sys.dm_exec_describe_first_result_set

Type Mapping

SQL Server Python Pydantic
INT, BIGINT, SMALLINT, TINYINT int int
VARCHAR, NVARCHAR, CHAR, NCHAR, TEXT str str
DATETIME, DATETIME2, DATE, SMALLDATETIME datetime datetime
BIT bool bool
DECIMAL, NUMERIC, FLOAT, REAL, MONEY float float
UNIQUEIDENTIFIER str str
Unknown types str + warning str

Development

# Clone and install
git clone https://github.com/Samuel-Urrego/Singularity
cd singularity
uv sync

# Run tests
uv run pytest

# Lint and type-check
uv run ruff check .
uv run mypy singularity/

# Install pre-commit hooks
uv run pre-commit install

License

MIT — see LICENSE for details.

Project details


Download files

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

Source Distribution

singularitysql-0.1.1.tar.gz (31.3 kB view details)

Uploaded Source

Built Distribution

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

singularitysql-0.1.1-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file singularitysql-0.1.1.tar.gz.

File metadata

  • Download URL: singularitysql-0.1.1.tar.gz
  • Upload date:
  • Size: 31.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for singularitysql-0.1.1.tar.gz
Algorithm Hash digest
SHA256 f58be0f4deeab72c79e5ce9cd70a064c870b39e674e7d496a09d351ef4148f90
MD5 0eeb54fd9ea4719e06c30626b0740a6e
BLAKE2b-256 2756f84e244456596c32173c23c05479b5b4105ba610d6f3a10a23a789893ec8

See more details on using hashes here.

Provenance

The following attestation bundles were made for singularitysql-0.1.1.tar.gz:

Publisher: publish.yml on Samuel-Urrego/Singularity

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

File details

Details for the file singularitysql-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: singularitysql-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for singularitysql-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0f82997e7d2e46df9fbcefb1d45f8de73728bb6b4fcadcf3a4ea9bf05e492cca
MD5 c54cd9c2695ad8bad832faa78b201a2b
BLAKE2b-256 78a042a82684c56fc7f890c7eeabfa1c706d075c5d3dd0115a13e62caee0ed5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for singularitysql-0.1.1-py3-none-any.whl:

Publisher: publish.yml on Samuel-Urrego/Singularity

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