iron-sql 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iron_sql-0.3.0 → iron_sql-0.4.0}/PKG-INFO +3 -2
- {iron_sql-0.3.0 → iron_sql-0.4.0}/README.md +1 -1
- {iron_sql-0.3.0 → iron_sql-0.4.0}/pyproject.toml +6 -9
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/codegen/generator.py +0 -33
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/codegen/sqlc.py +2 -30
- {iron_sql-0.3.0 → iron_sql-0.4.0}/LICENSE +0 -0
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/__init__.py +0 -0
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/codegen/__init__.py +0 -0
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/codegen/util.py +0 -0
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/py.typed +0 -0
- {iron_sql-0.3.0 → iron_sql-0.4.0}/src/iron_sql/runtime.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iron-sql
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: iron_sql generates typed async PostgreSQL clients and runtime helpers from schemas and SQL queries
|
|
5
5
|
Keywords: postgresql,sql,sqlc,psycopg,codegen,async
|
|
6
6
|
Author: Ilia Ablamonov
|
|
@@ -16,6 +16,7 @@ Requires-Dist: psycopg>=3.3.2
|
|
|
16
16
|
Requires-Dist: psycopg-pool>=3.3.0
|
|
17
17
|
Requires-Dist: pydantic>=2.12.4
|
|
18
18
|
Requires-Dist: inflection>=0.5.1 ; extra == 'codegen'
|
|
19
|
+
Requires-Dist: sqlc>=1.30.0 ; extra == 'codegen'
|
|
19
20
|
Requires-Python: >=3.13
|
|
20
21
|
Project-URL: Homepage, https://github.com/Flamefork/iron_sql
|
|
21
22
|
Project-URL: Repository, https://github.com/Flamefork/iron_sql.git
|
|
@@ -39,7 +40,7 @@ pip install iron-sql # runtime only (psycopg + psycopg-pool + pydant
|
|
|
39
40
|
pip install iron-sql[codegen] # + inflection for code generation
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
The `sqlc` binary is bundled automatically via the `sqlc` Python package.
|
|
43
44
|
|
|
44
45
|
## Key Features
|
|
45
46
|
- **Query discovery.** `generate_sql_package` scans your codebase for calls like `<package>_sql("SELECT ...")`, runs `sqlc` for type analysis, and emits a typed module.
|
|
@@ -14,7 +14,7 @@ pip install iron-sql # runtime only (psycopg + psycopg-pool + pydant
|
|
|
14
14
|
pip install iron-sql[codegen] # + inflection for code generation
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The `sqlc` binary is bundled automatically via the `sqlc` Python package.
|
|
18
18
|
|
|
19
19
|
## Key Features
|
|
20
20
|
- **Query discovery.** `generate_sql_package` scans your codebase for calls like `<package>_sql("SELECT ...")`, runs `sqlc` for type analysis, and emits a typed module.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "iron-sql"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
|
|
5
5
|
description = "iron_sql generates typed async PostgreSQL clients and runtime helpers from schemas and SQL queries"
|
|
6
6
|
readme = "README.md"
|
|
@@ -24,7 +24,10 @@ dependencies = [
|
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
[project.optional-dependencies]
|
|
27
|
-
codegen = [
|
|
27
|
+
codegen = [
|
|
28
|
+
"inflection>=0.5.1",
|
|
29
|
+
"sqlc>=1.30.0",
|
|
30
|
+
]
|
|
28
31
|
|
|
29
32
|
[project.urls]
|
|
30
33
|
Homepage = "https://github.com/Flamefork/iron_sql"
|
|
@@ -35,16 +38,9 @@ Issues = "https://github.com/Flamefork/iron_sql/issues"
|
|
|
35
38
|
requires = ["uv_build>=0.9.4,<0.10.0"]
|
|
36
39
|
build-backend = "uv_build"
|
|
37
40
|
|
|
38
|
-
[tool.uv.workspace]
|
|
39
|
-
members = ["dev"]
|
|
40
|
-
|
|
41
|
-
[tool.uv.sources]
|
|
42
|
-
iron-sql-dev = { workspace = true }
|
|
43
|
-
|
|
44
41
|
[dependency-groups]
|
|
45
42
|
dev = [
|
|
46
43
|
"iron-sql[codegen]",
|
|
47
|
-
"iron-sql-dev",
|
|
48
44
|
"basedpyright>=1.31.7",
|
|
49
45
|
"psycopg[binary]>=3.3.2",
|
|
50
46
|
"pytest>=8.4.2",
|
|
@@ -52,6 +48,7 @@ dev = [
|
|
|
52
48
|
"pytest-cov>=7.0.0",
|
|
53
49
|
"pytest-randomly>=4.0.1",
|
|
54
50
|
"ruff>=0.14.1",
|
|
51
|
+
"testcontainers>=4",
|
|
55
52
|
]
|
|
56
53
|
|
|
57
54
|
[tool.pyright]
|
|
@@ -198,39 +198,8 @@ def generate_sql_package( # noqa: PLR0913, PLR0914
|
|
|
198
198
|
to_snake_fn: Callable[[str], str] = alias_generators.to_snake,
|
|
199
199
|
debug_path: Path | None = None,
|
|
200
200
|
src_path: Path = Path(),
|
|
201
|
-
sqlc_path: Path | None = None,
|
|
202
201
|
tempdir_path: Path | None = None,
|
|
203
|
-
sqlc_command: list[str] | None = None,
|
|
204
202
|
) -> bool:
|
|
205
|
-
"""Generate a typed SQL package from schema and queries.
|
|
206
|
-
|
|
207
|
-
Args:
|
|
208
|
-
schema_path: Path to the Postgres schema SQL file (relative to src_path)
|
|
209
|
-
package_full_name: Target module name (e.g., "myapp.mydatabase")
|
|
210
|
-
dsn_import: Import path to DSN string (e.g.,
|
|
211
|
-
"myapp.config:CONFIG.db_url")
|
|
212
|
-
application_name: Optional application name for connection pool
|
|
213
|
-
type_overrides: Optional mapping of DB type name (without "pg_catalog.")
|
|
214
|
-
to a Python type string used in generated annotations.
|
|
215
|
-
json_model_overrides: Optional mapping of "table.column" to
|
|
216
|
-
"module:ClassName" for JSON model serialization/deserialization.
|
|
217
|
-
to_pascal_fn: Function to convert names to PascalCase (default:
|
|
218
|
-
pydantic's to_pascal)
|
|
219
|
-
to_snake_fn: Function to convert names to snake_case (default:
|
|
220
|
-
pydantic's to_snake)
|
|
221
|
-
debug_path: Optional path to save sqlc inputs for inspection
|
|
222
|
-
src_path: Base source path for scanning queries (default: Path())
|
|
223
|
-
sqlc_path: Optional path to sqlc config directory
|
|
224
|
-
tempdir_path: Optional path for temporary file generation
|
|
225
|
-
sqlc_command: Optional command prefix to run sqlc
|
|
226
|
-
|
|
227
|
-
Returns:
|
|
228
|
-
True if the package was generated or modified, False otherwise
|
|
229
|
-
|
|
230
|
-
Raises:
|
|
231
|
-
ValueError: If json_model_overrides keys/values are malformed,
|
|
232
|
-
reference non-existent tables/columns, or target non-JSON columns.
|
|
233
|
-
"""
|
|
234
203
|
dsn_import_package, dsn_import_path = dsn_import.split(":")
|
|
235
204
|
|
|
236
205
|
package_name = package_full_name.split(".")[-1] # noqa: PLC0207
|
|
@@ -250,9 +219,7 @@ def generate_sql_package( # noqa: PLR0913, PLR0914
|
|
|
250
219
|
[(q.name, q.stmt) for q in queries],
|
|
251
220
|
dsn=dsn,
|
|
252
221
|
debug_path=debug_path,
|
|
253
|
-
sqlc_path=sqlc_path,
|
|
254
222
|
tempdir_path=tempdir_path,
|
|
255
|
-
sqlc_command=sqlc_command,
|
|
256
223
|
)
|
|
257
224
|
|
|
258
225
|
if sqlc_res.error:
|
|
@@ -8,6 +8,7 @@ from collections.abc import Sequence
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
import pydantic
|
|
11
|
+
import sqlc
|
|
11
12
|
from pydantic import ConfigDict
|
|
12
13
|
|
|
13
14
|
|
|
@@ -131,41 +132,13 @@ class SQLCResult(pydantic.BaseModel):
|
|
|
131
132
|
return tuple(s for s in result if s in catalog_schema_names)
|
|
132
133
|
|
|
133
134
|
|
|
134
|
-
def resolve_sqlc_command(
|
|
135
|
-
sqlc_path: Path | None,
|
|
136
|
-
sqlc_command: list[str] | None,
|
|
137
|
-
) -> list[str]:
|
|
138
|
-
if sqlc_command is not None:
|
|
139
|
-
if sqlc_path is not None:
|
|
140
|
-
msg = "sqlc_command and sqlc_path are mutually exclusive"
|
|
141
|
-
raise ValueError(msg)
|
|
142
|
-
if not sqlc_command:
|
|
143
|
-
msg = "sqlc_command must not be empty"
|
|
144
|
-
raise ValueError(msg)
|
|
145
|
-
return sqlc_command
|
|
146
|
-
|
|
147
|
-
if sqlc_path is None:
|
|
148
|
-
discovered_path = shutil.which("sqlc")
|
|
149
|
-
if discovered_path is None:
|
|
150
|
-
msg = "sqlc not found in PATH"
|
|
151
|
-
raise FileNotFoundError(msg)
|
|
152
|
-
sqlc_path = Path(discovered_path)
|
|
153
|
-
if not sqlc_path.exists():
|
|
154
|
-
msg = f"sqlc not found at {sqlc_path}"
|
|
155
|
-
raise FileNotFoundError(msg)
|
|
156
|
-
|
|
157
|
-
return [str(sqlc_path)]
|
|
158
|
-
|
|
159
|
-
|
|
160
135
|
def run_sqlc(
|
|
161
136
|
schema_path: Path,
|
|
162
137
|
queries: Sequence[tuple[str, str]],
|
|
163
138
|
*,
|
|
164
139
|
dsn: str | None,
|
|
165
140
|
debug_path: Path | None = None,
|
|
166
|
-
sqlc_path: Path | None = None,
|
|
167
141
|
tempdir_path: Path | None = None,
|
|
168
|
-
sqlc_command: list[str] | None = None,
|
|
169
142
|
) -> SQLCResult:
|
|
170
143
|
if not schema_path.exists():
|
|
171
144
|
msg = f"Schema file not found: {schema_path}"
|
|
@@ -178,7 +151,6 @@ def run_sqlc(
|
|
|
178
151
|
)
|
|
179
152
|
|
|
180
153
|
queries = list({q[0]: q for q in queries}.values())
|
|
181
|
-
cmd_prefix = resolve_sqlc_command(sqlc_path, sqlc_command)
|
|
182
154
|
|
|
183
155
|
with tempfile.TemporaryDirectory(
|
|
184
156
|
dir=str(tempdir_path) if tempdir_path else None
|
|
@@ -209,7 +181,7 @@ def run_sqlc(
|
|
|
209
181
|
}
|
|
210
182
|
config_path.write_text(json.dumps(sqlc_config, indent=2), encoding="utf-8")
|
|
211
183
|
|
|
212
|
-
cmd = [
|
|
184
|
+
cmd = [sqlc.get_binary_path(), "generate", "--file", str(config_path.resolve())]
|
|
213
185
|
|
|
214
186
|
sqlc_run_result = subprocess.run( # noqa: S603
|
|
215
187
|
cmd,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|