From 0a9dcb769588ef94786c23354d664cfcee2c0415 Mon Sep 17 00:00:00 2001 From: Merlin Ran Date: Tue, 24 Feb 2026 19:04:57 +0000 Subject: [PATCH 1/3] Support type overrides with test coveragfixtures Also updated tests to the latest sqlc version --- README.md | 48 +++++++ examples/src/authors/models.py | 2 +- examples/src/authors/query.py | 2 +- examples/src/booktest/models.py | 2 +- examples/src/booktest/query.py | 2 +- examples/src/jets/models.py | 2 +- examples/src/jets/query-building.py | 2 +- examples/src/ondeck/city.py | 2 +- examples/src/ondeck/models.py | 2 +- examples/src/ondeck/venue.py | 2 +- internal/config.go | 1 + .../db/models.py | 2 +- .../db/query.py | 2 +- .../sqlc.yaml | 2 +- .../emit_pydantic_models/db/models.py | 2 +- .../testdata/emit_pydantic_models/db/query.py | 2 +- .../testdata/emit_pydantic_models/sqlc.yaml | 2 +- .../db/models.py | 2 +- .../db/query.py | 2 +- .../sqlc.yaml | 2 +- .../testdata/emit_str_enum/db/models.py | 2 +- .../testdata/emit_str_enum/db/query.py | 2 +- .../endtoend/testdata/emit_str_enum/sqlc.yaml | 2 +- .../testdata/emit_type_overrides/db/models.py | 24 ++++ .../testdata/emit_type_overrides/db/query.py | 133 ++++++++++++++++++ .../testdata/emit_type_overrides/query.sql | 18 +++ .../testdata/emit_type_overrides/schema.sql | 10 ++ .../testdata/emit_type_overrides/sqlc.yaml | 25 ++++ .../testdata/exec_result/python/models.py | 2 +- .../testdata/exec_result/python/query.py | 2 +- .../endtoend/testdata/exec_result/sqlc.yaml | 2 +- .../testdata/exec_rows/python/models.py | 2 +- .../testdata/exec_rows/python/query.py | 2 +- .../endtoend/testdata/exec_rows/sqlc.yaml | 2 +- .../python/models.py | 2 +- .../python/query.py | 2 +- .../inflection_exclude_table_names/sqlc.yaml | 2 +- .../python/models.py | 2 +- .../query_parameter_limit_two/python/query.py | 2 +- .../query_parameter_limit_two/sqlc.yaml | 2 +- .../python/models.py | 2 +- .../python/query.py | 2 +- .../query_parameter_limit_undefined/sqlc.yaml | 2 +- .../python/models.py | 2 +- .../python/query.py | 2 +- .../query_parameter_limit_zero/sqlc.yaml | 2 +- .../query_parameter_no_limit/sqlc.yaml | 2 +- internal/gen.go | 37 +++-- 48 files changed, 328 insertions(+), 48 deletions(-) create mode 100644 internal/endtoend/testdata/emit_type_overrides/db/models.py create mode 100644 internal/endtoend/testdata/emit_type_overrides/db/query.py create mode 100644 internal/endtoend/testdata/emit_type_overrides/query.sql create mode 100644 internal/endtoend/testdata/emit_type_overrides/schema.sql create mode 100644 internal/endtoend/testdata/emit_type_overrides/sqlc.yaml diff --git a/README.md b/README.md index d10bd8d..d2fe13f 100644 --- a/README.md +++ b/README.md @@ -99,3 +99,51 @@ class Status(str, enum.Enum): OPEN = "op!en" CLOSED = "clo@sed" ``` + +### Override Column Types + +Option: `overrides` + +You can override the SQL to Python type mapping for specific columns or database types using the `overrides` option. This is useful for columns with JSON data or other custom types. + +Example configuration: + +```yaml +options: + package: authors + emit_pydantic_models: true + overrides: + - column: "some_table.payload" + py_import: "my_lib.models" + py_type: "Payload" + - db_type: "jsonb" + py_import: "my_lib.models" + py_type: "Payload" +``` + +This will: +1. Override the column `payload` in `some_table` to use the type `Payload` +2. Override any column with the database type `jsonb` to use the type `Payload` +3. Add an import for `my_lib.models` to the models file + +Example output: + +```python +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.30.0 + +import datetime +import pydantic +from typing import Any + +import my_lib.models + + +class SomeTable(pydantic.BaseModel): + id: int + created_at: datetime.datetime + payload: my_lib.models.Payload +``` + +This is similar to the [overrides functionality in the Go version of sqlc](https://docs.sqlc.dev/en/stable/howto/overrides.html#overriding-types). diff --git a/examples/src/authors/models.py b/examples/src/authors/models.py index b3b9554..007ea19 100644 --- a/examples/src/authors/models.py +++ b/examples/src/authors/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses from typing import Optional diff --git a/examples/src/authors/query.py b/examples/src/authors/query.py index b932e35..48513ed 100644 --- a/examples/src/authors/query.py +++ b/examples/src/authors/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql from typing import AsyncIterator, Iterator, Optional diff --git a/examples/src/booktest/models.py b/examples/src/booktest/models.py index dcfbc20..a882d02 100644 --- a/examples/src/booktest/models.py +++ b/examples/src/booktest/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses import datetime import enum diff --git a/examples/src/booktest/query.py b/examples/src/booktest/query.py index 12d3717..6e71192 100644 --- a/examples/src/booktest/query.py +++ b/examples/src/booktest/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql import dataclasses import datetime diff --git a/examples/src/jets/models.py b/examples/src/jets/models.py index fc5464b..7d9a81e 100644 --- a/examples/src/jets/models.py +++ b/examples/src/jets/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/examples/src/jets/query-building.py b/examples/src/jets/query-building.py index adcdcdb..51d69a5 100644 --- a/examples/src/jets/query-building.py +++ b/examples/src/jets/query-building.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query-building.sql from typing import AsyncIterator, Optional diff --git a/examples/src/ondeck/city.py b/examples/src/ondeck/city.py index 2f2da93..951d95b 100644 --- a/examples/src/ondeck/city.py +++ b/examples/src/ondeck/city.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: city.sql from typing import AsyncIterator, Optional diff --git a/examples/src/ondeck/models.py b/examples/src/ondeck/models.py index a32fea2..bc05e8a 100644 --- a/examples/src/ondeck/models.py +++ b/examples/src/ondeck/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses import datetime import enum diff --git a/examples/src/ondeck/venue.py b/examples/src/ondeck/venue.py index 1911cb3..87f7992 100644 --- a/examples/src/ondeck/venue.py +++ b/examples/src/ondeck/venue.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: venue.sql import dataclasses from typing import AsyncIterator, List, Optional diff --git a/internal/config.go b/internal/config.go index 8fc6a0a..6f0f669 100644 --- a/internal/config.go +++ b/internal/config.go @@ -2,6 +2,7 @@ package python type OverrideColumn struct { Column string `json:"column"` + DbType string `json:"db_type"` PyType string `json:"py_type"` PyImport string `json:"py_import"` } diff --git a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py index f2dd802..50ed88f 100644 --- a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py +++ b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/query.py b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/query.py index 1a0ac38..5ee401b 100644 --- a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/query.py +++ b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql from typing import Optional diff --git a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml index a7cfc22..56d1cac 100644 --- a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml +++ b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models/db/models.py b/internal/endtoend/testdata/emit_pydantic_models/db/models.py index 5c6947e..8b96b15 100644 --- a/internal/endtoend/testdata/emit_pydantic_models/db/models.py +++ b/internal/endtoend/testdata/emit_pydantic_models/db/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import pydantic from typing import Optional diff --git a/internal/endtoend/testdata/emit_pydantic_models/db/query.py b/internal/endtoend/testdata/emit_pydantic_models/db/query.py index cc36118..946674d 100644 --- a/internal/endtoend/testdata/emit_pydantic_models/db/query.py +++ b/internal/endtoend/testdata/emit_pydantic_models/db/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql from typing import AsyncIterator, Iterator, Optional diff --git a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml index bc03370..5cb5d25 100644 --- a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/models.py b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/models.py index 1403269..8003649 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/models.py +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import pydantic diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/query.py b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/query.py index 1a0ac38..5ee401b 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/query.py +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql from typing import Optional diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml index bc03370..5cb5d25 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_str_enum/db/models.py b/internal/endtoend/testdata/emit_str_enum/db/models.py index aa43ab1..5fd5508 100644 --- a/internal/endtoend/testdata/emit_str_enum/db/models.py +++ b/internal/endtoend/testdata/emit_str_enum/db/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses import enum from typing import Optional diff --git a/internal/endtoend/testdata/emit_str_enum/db/query.py b/internal/endtoend/testdata/emit_str_enum/db/query.py index 5ea0264..c02a9ec 100644 --- a/internal/endtoend/testdata/emit_str_enum/db/query.py +++ b/internal/endtoend/testdata/emit_str_enum/db/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql from typing import AsyncIterator, Iterator, Optional diff --git a/internal/endtoend/testdata/emit_str_enum/sqlc.yaml b/internal/endtoend/testdata/emit_str_enum/sqlc.yaml index 1a80fbc..a79fdd2 100644 --- a/internal/endtoend/testdata/emit_str_enum/sqlc.yaml +++ b/internal/endtoend/testdata/emit_str_enum/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_type_overrides/db/models.py b/internal/endtoend/testdata/emit_type_overrides/db/models.py new file mode 100644 index 0000000..10f1b05 --- /dev/null +++ b/internal/endtoend/testdata/emit_type_overrides/db/models.py @@ -0,0 +1,24 @@ +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.30.0 +import enum +import pydantic +from typing import Optional + + +class BookStatus(str, enum.Enum): + AVAILABLE = "available" + CHECKED_OUT = "checked_out" + OVERDUE = "overdue" + + +class Book(pydantic.BaseModel): + model_config = pydantic.ConfigDict( + validate_by_alias=True, + validate_by_name=True, + ) + id: int + title: str + status: Optional[BookStatus] + payload: my_lib.models.BookPayload + metadata: Optional[my_lib.models.JsonValue] diff --git a/internal/endtoend/testdata/emit_type_overrides/db/query.py b/internal/endtoend/testdata/emit_type_overrides/db/query.py new file mode 100644 index 0000000..e60e74e --- /dev/null +++ b/internal/endtoend/testdata/emit_type_overrides/db/query.py @@ -0,0 +1,133 @@ +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.30.0 +# source: query.sql +from typing import AsyncIterator, Iterator, Optional + +import sqlalchemy +import sqlalchemy.ext.asyncio + +from db import models + + +CREATE_BOOK = """-- name: create_book \\:one +INSERT INTO books ( + title, status, payload, metadata +) VALUES ( + :p1, :p2, :p3, :p4 +) RETURNING id, title, status, payload, metadata +""" + + +DELETE_BOOK = """-- name: delete_book \\:exec +DELETE FROM books +WHERE id = :p1 +""" + + +GET_BOOK = """-- name: get_book \\:one +SELECT id, title, status, payload, metadata FROM books +WHERE id = :p1 LIMIT 1 +""" + + +LIST_BOOKS = """-- name: list_books \\:many +SELECT id, title, status, payload, metadata FROM books +ORDER BY title +""" + + +class Querier: + def __init__(self, conn: sqlalchemy.engine.Connection): + self._conn = conn + + def create_book(self, *, title: str, status: Optional[models.BookStatus], payload: my_lib.models.BookPayload, metadata: Optional[my_lib.models.JsonValue]) -> Optional[models.Book]: + row = self._conn.execute(sqlalchemy.text(CREATE_BOOK), { + "p1": title, + "p2": status, + "p3": payload, + "p4": metadata, + }).first() + if row is None: + return None + return models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) + + def delete_book(self, *, id: int) -> None: + self._conn.execute(sqlalchemy.text(DELETE_BOOK), {"p1": id}) + + def get_book(self, *, id: int) -> Optional[models.Book]: + row = self._conn.execute(sqlalchemy.text(GET_BOOK), {"p1": id}).first() + if row is None: + return None + return models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) + + def list_books(self) -> Iterator[models.Book]: + result = self._conn.execute(sqlalchemy.text(LIST_BOOKS)) + for row in result: + yield models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) + + +class AsyncQuerier: + def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection): + self._conn = conn + + async def create_book(self, *, title: str, status: Optional[models.BookStatus], payload: my_lib.models.BookPayload, metadata: Optional[my_lib.models.JsonValue]) -> Optional[models.Book]: + row = (await self._conn.execute(sqlalchemy.text(CREATE_BOOK), { + "p1": title, + "p2": status, + "p3": payload, + "p4": metadata, + })).first() + if row is None: + return None + return models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) + + async def delete_book(self, *, id: int) -> None: + await self._conn.execute(sqlalchemy.text(DELETE_BOOK), {"p1": id}) + + async def get_book(self, *, id: int) -> Optional[models.Book]: + row = (await self._conn.execute(sqlalchemy.text(GET_BOOK), {"p1": id})).first() + if row is None: + return None + return models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) + + async def list_books(self) -> AsyncIterator[models.Book]: + result = await self._conn.stream(sqlalchemy.text(LIST_BOOKS)) + async for row in result: + yield models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) diff --git a/internal/endtoend/testdata/emit_type_overrides/query.sql b/internal/endtoend/testdata/emit_type_overrides/query.sql new file mode 100644 index 0000000..7214d43 --- /dev/null +++ b/internal/endtoend/testdata/emit_type_overrides/query.sql @@ -0,0 +1,18 @@ +-- name: GetBook :one +SELECT * FROM books +WHERE id = $1 LIMIT 1; + +-- name: ListBooks :many +SELECT * FROM books +ORDER BY title; + +-- name: CreateBook :one +INSERT INTO books ( + title, status, payload, metadata +) VALUES ( + $1, $2, $3, $4 +) RETURNING *; + +-- name: DeleteBook :exec +DELETE FROM books +WHERE id = $1; diff --git a/internal/endtoend/testdata/emit_type_overrides/schema.sql b/internal/endtoend/testdata/emit_type_overrides/schema.sql new file mode 100644 index 0000000..51c1c9f --- /dev/null +++ b/internal/endtoend/testdata/emit_type_overrides/schema.sql @@ -0,0 +1,10 @@ +CREATE TYPE book_status AS ENUM ('available', 'checked_out', 'overdue'); + + +CREATE TABLE books ( + id BIGSERIAL PRIMARY KEY, + title text NOT NULL, + status book_status DEFAULT 'available', + payload jsonb NOT NULL, + metadata jsonb +); diff --git a/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml b/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml new file mode 100644 index 0000000..75d9869 --- /dev/null +++ b/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml @@ -0,0 +1,25 @@ +version: "2" +plugins: + - name: py + wasm: + url: file://../../../../bin/sqlc-gen-python.wasm + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" +sql: + - schema: schema.sql + queries: query.sql + engine: postgresql + codegen: + - plugin: py + out: db + options: + package: db + emit_pydantic_models: true + emit_sync_querier: true + emit_async_querier: true + overrides: + - column: "books.payload" + py_import: "my_lib.models" + py_type: "BookPayload" + - db_type: "jsonb" + py_import: "my_lib.models" + py_type: "JsonValue" diff --git a/internal/endtoend/testdata/exec_result/python/models.py b/internal/endtoend/testdata/exec_result/python/models.py index 6d3e9f5..ced3715 100644 --- a/internal/endtoend/testdata/exec_result/python/models.py +++ b/internal/endtoend/testdata/exec_result/python/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/exec_result/python/query.py b/internal/endtoend/testdata/exec_result/python/query.py index c9c6e21..c063868 100644 --- a/internal/endtoend/testdata/exec_result/python/query.py +++ b/internal/endtoend/testdata/exec_result/python/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql import sqlalchemy import sqlalchemy.ext.asyncio diff --git a/internal/endtoend/testdata/exec_result/sqlc.yaml b/internal/endtoend/testdata/exec_result/sqlc.yaml index 9c6a7d3..14eb4ef 100644 --- a/internal/endtoend/testdata/exec_result/sqlc.yaml +++ b/internal/endtoend/testdata/exec_result/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/exec_rows/python/models.py b/internal/endtoend/testdata/exec_rows/python/models.py index 6d3e9f5..ced3715 100644 --- a/internal/endtoend/testdata/exec_rows/python/models.py +++ b/internal/endtoend/testdata/exec_rows/python/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/exec_rows/python/query.py b/internal/endtoend/testdata/exec_rows/python/query.py index a678f3d..c5a936d 100644 --- a/internal/endtoend/testdata/exec_rows/python/query.py +++ b/internal/endtoend/testdata/exec_rows/python/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql import sqlalchemy import sqlalchemy.ext.asyncio diff --git a/internal/endtoend/testdata/exec_rows/sqlc.yaml b/internal/endtoend/testdata/exec_rows/sqlc.yaml index 9c6a7d3..14eb4ef 100644 --- a/internal/endtoend/testdata/exec_rows/sqlc.yaml +++ b/internal/endtoend/testdata/exec_rows/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/inflection_exclude_table_names/python/models.py b/internal/endtoend/testdata/inflection_exclude_table_names/python/models.py index fc76620..0614ac0 100644 --- a/internal/endtoend/testdata/inflection_exclude_table_names/python/models.py +++ b/internal/endtoend/testdata/inflection_exclude_table_names/python/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/inflection_exclude_table_names/python/query.py b/internal/endtoend/testdata/inflection_exclude_table_names/python/query.py index 1fc92fd..8b9eb26 100644 --- a/internal/endtoend/testdata/inflection_exclude_table_names/python/query.py +++ b/internal/endtoend/testdata/inflection_exclude_table_names/python/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql from typing import Optional diff --git a/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml b/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml index 369271f..dc0208b 100644 --- a/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml +++ b/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_limit_two/python/models.py b/internal/endtoend/testdata/query_parameter_limit_two/python/models.py index 89c0f8d..2ddf019 100644 --- a/internal/endtoend/testdata/query_parameter_limit_two/python/models.py +++ b/internal/endtoend/testdata/query_parameter_limit_two/python/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/query_parameter_limit_two/python/query.py b/internal/endtoend/testdata/query_parameter_limit_two/python/query.py index 0d9bd97..5a97c59 100644 --- a/internal/endtoend/testdata/query_parameter_limit_two/python/query.py +++ b/internal/endtoend/testdata/query_parameter_limit_two/python/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql import sqlalchemy import sqlalchemy.ext.asyncio diff --git a/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml b/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml index 6d7d162..d837147 100644 --- a/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_limit_undefined/python/models.py b/internal/endtoend/testdata/query_parameter_limit_undefined/python/models.py index dc09dab..77bdfe5 100644 --- a/internal/endtoend/testdata/query_parameter_limit_undefined/python/models.py +++ b/internal/endtoend/testdata/query_parameter_limit_undefined/python/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/query_parameter_limit_undefined/python/query.py b/internal/endtoend/testdata/query_parameter_limit_undefined/python/query.py index 49b7bd1..6380dce 100644 --- a/internal/endtoend/testdata/query_parameter_limit_undefined/python/query.py +++ b/internal/endtoend/testdata/query_parameter_limit_undefined/python/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql import sqlalchemy import sqlalchemy.ext.asyncio diff --git a/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml b/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml index 4ba6c57..7d1f505 100644 --- a/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_limit_zero/python/models.py b/internal/endtoend/testdata/query_parameter_limit_zero/python/models.py index 89c0f8d..2ddf019 100644 --- a/internal/endtoend/testdata/query_parameter_limit_zero/python/models.py +++ b/internal/endtoend/testdata/query_parameter_limit_zero/python/models.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 import dataclasses diff --git a/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py b/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py index 38e0efb..5edcd9c 100644 --- a/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py +++ b/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py @@ -1,6 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. # versions: -# sqlc v1.29.0 +# sqlc v1.30.0 # source: query.sql import dataclasses diff --git a/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml b/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml index 4c1abd2..7f66fa2 100644 --- a/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml b/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml index 270c290..798e0f8 100644 --- a/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" + sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" sql: - schema: schema.sql queries: query.sql diff --git a/internal/gen.go b/internal/gen.go index 0c145ea..ffd64d7 100644 --- a/internal/gen.go +++ b/internal/gen.go @@ -190,17 +190,38 @@ func makePyType(req *plugin.GenerateRequest, col *plugin.Column) pyType { } // Check for overrides - if len(conf.Overrides) > 0 && col.Table != nil { - tableName := col.Table.Name - if col.Table.Schema != "" && col.Table.Schema != req.Catalog.DefaultSchema { - tableName = col.Table.Schema + "." + tableName + if len(conf.Overrides) > 0 { + if col.Table != nil { + tableName := col.Table.Name + if col.Table.Schema != "" && col.Table.Schema != req.Catalog.DefaultSchema { + tableName = col.Table.Schema + "." + tableName + } + + // Look for a matching column override first + for _, override := range conf.Overrides { + overrideKey := tableName + "." + col.Name + if override.Column == overrideKey { + // Found a match, use the override + typeStr := override.PyType + if override.PyImport != "" && !strings.Contains(typeStr, ".") { + typeStr = override.PyImport + "." + override.PyType + } + return pyType{ + InnerType: typeStr, + IsArray: col.IsArray, + IsNull: !col.NotNull, + } + } + } } - // Look for a matching override + // Then look for a matching db_type override + columnType := strings.ToLower(sdk.DataType(col.Type)) for _, override := range conf.Overrides { - overrideKey := tableName + "." + col.Name - if override.Column == overrideKey { - // Found a match, use the override + if override.DbType == "" { + continue + } + if strings.EqualFold(override.DbType, columnType) { typeStr := override.PyType if override.PyImport != "" && !strings.Contains(typeStr, ".") { typeStr = override.PyImport + "." + override.PyType From 86a9e4e6a519e1e781c18dff7276411af68117f6 Mon Sep 17 00:00:00 2001 From: Merlin Ran Date: Tue, 24 Feb 2026 20:23:03 +0000 Subject: [PATCH 2/3] fail for unknown yaml fields --- internal/config.go | 23 +++++++++++++ internal/config_test.go | 32 +++++++++++++++++++ .../sqlc.yaml | 2 +- .../testdata/emit_pydantic_models/sqlc.yaml | 2 +- .../sqlc.yaml | 2 +- .../endtoend/testdata/emit_str_enum/sqlc.yaml | 2 +- .../testdata/emit_type_overrides/db/query.py | 29 +++++++++++++++++ .../testdata/emit_type_overrides/query.sql | 5 +++ .../testdata/emit_type_overrides/sqlc.yaml | 2 +- .../endtoend/testdata/exec_result/sqlc.yaml | 2 +- .../endtoend/testdata/exec_rows/sqlc.yaml | 2 +- .../inflection_exclude_table_names/sqlc.yaml | 2 +- .../query_parameter_limit_two/sqlc.yaml | 2 +- .../query_parameter_limit_undefined/sqlc.yaml | 2 +- .../query_parameter_limit_zero/sqlc.yaml | 2 +- .../query_parameter_no_limit/sqlc.yaml | 2 +- internal/gen.go | 15 ++++----- 17 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 internal/config_test.go diff --git a/internal/config.go b/internal/config.go index 6f0f669..a024dce 100644 --- a/internal/config.go +++ b/internal/config.go @@ -1,5 +1,12 @@ package python +import ( + "bytes" + json "encoding/json" + "fmt" + "strings" +) + type OverrideColumn struct { Column string `json:"column"` DbType string `json:"db_type"` @@ -20,3 +27,19 @@ type Config struct { InflectionExcludeTableNames []string `json:"inflection_exclude_table_names"` Overrides []OverrideColumn `json:"overrides"` } + +func parseConfig(raw []byte) (Config, error) { + var conf Config + if len(raw) == 0 { + return conf, nil + } + + dec := json.NewDecoder(bytes.NewReader(raw)) + dec.DisallowUnknownFields() + if err := dec.Decode(&conf); err != nil { + msg := strings.TrimPrefix(err.Error(), "json: ") + return Config{}, fmt.Errorf("invalid plugin options: %s", msg) + } + + return conf, nil +} diff --git a/internal/config_test.go b/internal/config_test.go new file mode 100644 index 0000000..c7d515f --- /dev/null +++ b/internal/config_test.go @@ -0,0 +1,32 @@ +package python + +import ( + "strings" + "testing" +) + +func TestParseConfigDisallowUnknownFields(t *testing.T) { + _, err := parseConfig([]byte(`{"emit_sync_querier":true,"db_typ":"jsonb"}`)) + if err == nil { + t.Fatal("expected unknown field error, got nil") + } + if !strings.Contains(err.Error(), "invalid plugin options") { + t.Fatalf("expected error to reference plugin options, got: %v", err) + } + if !strings.Contains(err.Error(), `unknown field "db_typ"`) { + t.Fatalf("expected unknown field in error, got: %v", err) + } +} + +func TestParseConfigValid(t *testing.T) { + conf, err := parseConfig([]byte(`{"emit_sync_querier":true,"overrides":[{"db_type":"jsonb","py_type":"str"}]}`)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !conf.EmitSyncQuerier { + t.Fatal("expected emit_sync_querier to be true") + } + if len(conf.Overrides) != 1 || conf.Overrides[0].DbType != "jsonb" || conf.Overrides[0].PyType != "str" { + t.Fatal("unexpected parsed overrides") + } +} diff --git a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml index 56d1cac..bb7f0e0 100644 --- a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml +++ b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml index 5cb5d25..483362d 100644 --- a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml index 5cb5d25..483362d 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_str_enum/sqlc.yaml b/internal/endtoend/testdata/emit_str_enum/sqlc.yaml index a79fdd2..4e08a4b 100644 --- a/internal/endtoend/testdata/emit_str_enum/sqlc.yaml +++ b/internal/endtoend/testdata/emit_str_enum/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_type_overrides/db/query.py b/internal/endtoend/testdata/emit_type_overrides/db/query.py index e60e74e..d160b11 100644 --- a/internal/endtoend/testdata/emit_type_overrides/db/query.py +++ b/internal/endtoend/testdata/emit_type_overrides/db/query.py @@ -37,6 +37,13 @@ """ +SEARCH_BOOKS = """-- name: search_books \\:many +SELECT id, title, status, payload, metadata FROM books +WHERE payload @> COALESCE(:p1\\:\\:jsonb, '{}'\\:\\:jsonb) +ORDER BY title +""" + + class Querier: def __init__(self, conn: sqlalchemy.engine.Connection): self._conn = conn @@ -84,6 +91,17 @@ def list_books(self) -> Iterator[models.Book]: metadata=row[4], ) + def search_books(self, *, payload_filter: Optional[my_lib.models.JsonValue]) -> Iterator[models.Book]: + result = self._conn.execute(sqlalchemy.text(SEARCH_BOOKS), {"p1": payload_filter}) + for row in result: + yield models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) + class AsyncQuerier: def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection): @@ -131,3 +149,14 @@ async def list_books(self) -> AsyncIterator[models.Book]: payload=row[3], metadata=row[4], ) + + async def search_books(self, *, payload_filter: Optional[my_lib.models.JsonValue]) -> AsyncIterator[models.Book]: + result = await self._conn.stream(sqlalchemy.text(SEARCH_BOOKS), {"p1": payload_filter}) + async for row in result: + yield models.Book( + id=row[0], + title=row[1], + status=row[2], + payload=row[3], + metadata=row[4], + ) diff --git a/internal/endtoend/testdata/emit_type_overrides/query.sql b/internal/endtoend/testdata/emit_type_overrides/query.sql index 7214d43..27240c2 100644 --- a/internal/endtoend/testdata/emit_type_overrides/query.sql +++ b/internal/endtoend/testdata/emit_type_overrides/query.sql @@ -16,3 +16,8 @@ INSERT INTO books ( -- name: DeleteBook :exec DELETE FROM books WHERE id = $1; + +-- name: SearchBooks :many +SELECT * FROM books +WHERE payload @> COALESCE(sqlc.narg('payload_filter')::jsonb, '{}'::jsonb) +ORDER BY title; diff --git a/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml b/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml index 75d9869..a254cc1 100644 --- a/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml +++ b/internal/endtoend/testdata/emit_type_overrides/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/exec_result/sqlc.yaml b/internal/endtoend/testdata/exec_result/sqlc.yaml index 14eb4ef..ad2de60 100644 --- a/internal/endtoend/testdata/exec_result/sqlc.yaml +++ b/internal/endtoend/testdata/exec_result/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/exec_rows/sqlc.yaml b/internal/endtoend/testdata/exec_rows/sqlc.yaml index 14eb4ef..ad2de60 100644 --- a/internal/endtoend/testdata/exec_rows/sqlc.yaml +++ b/internal/endtoend/testdata/exec_rows/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml b/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml index dc0208b..00c46bc 100644 --- a/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml +++ b/internal/endtoend/testdata/inflection_exclude_table_names/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml b/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml index d837147..6818f81 100644 --- a/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_limit_two/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml b/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml index 7d1f505..c274b43 100644 --- a/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_limit_undefined/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml b/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml index 7f66fa2..61ade44 100644 --- a/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_limit_zero/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml b/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml index 798e0f8..a1301c7 100644 --- a/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml +++ b/internal/endtoend/testdata/query_parameter_no_limit/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "77e9665cec6efe4e1871218c27a09143eb0f23fb509855c881757022383813e0" + sha256: "a5d1ad0ead1ecadb0608684d7c7a04327762299b769e6cca9c8f838c5df89788" sql: - schema: schema.sql queries: query.sql diff --git a/internal/gen.go b/internal/gen.go index ffd64d7..5132c9e 100644 --- a/internal/gen.go +++ b/internal/gen.go @@ -2,7 +2,6 @@ package python import ( "context" - json "encoding/json" "errors" "fmt" "log" @@ -181,11 +180,13 @@ func (q Query) ArgDictNode() *pyast.Node { } func makePyType(req *plugin.GenerateRequest, col *plugin.Column) pyType { - // Parse the configuration var conf Config if len(req.PluginOptions) > 0 { - if err := json.Unmarshal(req.PluginOptions, &conf); err != nil { + parsed, err := parseConfig(req.PluginOptions) + if err != nil { log.Printf("failed to parse plugin options: %s", err) + } else { + conf = parsed } } @@ -1233,11 +1234,9 @@ func HashComment(s string) string { } func Generate(_ context.Context, req *plugin.GenerateRequest) (*plugin.GenerateResponse, error) { - var conf Config - if len(req.PluginOptions) > 0 { - if err := json.Unmarshal(req.PluginOptions, &conf); err != nil { - return nil, err - } + conf, err := parseConfig(req.PluginOptions) + if err != nil { + return nil, err } enums := buildEnums(conf, req) From 619f15bcf28d438d29d8db4714e6008f61dba819 Mon Sep 17 00:00:00 2001 From: Merlin Ran Date: Tue, 24 Feb 2026 20:28:11 +0000 Subject: [PATCH 3/3] fix ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea4c783..56df2c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: go-version: '1.23.5' - uses: sqlc-dev/setup-sqlc@v4 with: - sqlc-version: '1.29.0' + sqlc-version: '1.30.0' - run: make - run: make test - run: sqlc diff