From 19e8d56813a83664bc19c12a3121e84e8bc7af66 Mon Sep 17 00:00:00 2001 From: QuentinN42 Date: Fri, 25 Jul 2025 15:37:07 +0200 Subject: [PATCH 1/5] feat: added invalid test for invalid name generation when using python reserved keywords Signed-off-by: QuentinN42 --- 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/endtoend/endtoend_test.go | 2 +- .../emit_pydantic_models/db/models.py | 2 +- .../testdata/emit_pydantic_models/db/query.py | 2 +- .../testdata/emit_pydantic_models/sqlc.yaml | 2 +- .../db/__init__.py | 0 .../db/models.py | 9 ++++ .../db/query.py | 44 +++++++++++++++++++ .../query.sql | 3 ++ .../schema.sql | 4 ++ .../sqlc.yaml | 18 ++++++++ .../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/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 +- 41 files changed, 113 insertions(+), 35 deletions(-) create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_fields/db/__init__.py create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_fields/query.sql create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_fields/schema.sql create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml diff --git a/examples/src/authors/models.py b/examples/src/authors/models.py index 96553a5..b3b9554 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.28.0 +# sqlc v1.29.0 import dataclasses from typing import Optional diff --git a/examples/src/authors/query.py b/examples/src/authors/query.py index 019f877..b932e35 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.28.0 +# sqlc v1.29.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 d7ee131..dcfbc20 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.28.0 +# sqlc v1.29.0 import dataclasses import datetime import enum diff --git a/examples/src/booktest/query.py b/examples/src/booktest/query.py index bc71f22..12d3717 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.28.0 +# sqlc v1.29.0 # source: query.sql import dataclasses import datetime diff --git a/examples/src/jets/models.py b/examples/src/jets/models.py index 0d4eb5d..fc5464b 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.28.0 +# sqlc v1.29.0 import dataclasses diff --git a/examples/src/jets/query-building.py b/examples/src/jets/query-building.py index 7651116..adcdcdb 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.28.0 +# sqlc v1.29.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 5af93e9..2f2da93 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.28.0 +# sqlc v1.29.0 # source: city.sql from typing import AsyncIterator, Optional diff --git a/examples/src/ondeck/models.py b/examples/src/ondeck/models.py index 1161408..a32fea2 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.28.0 +# sqlc v1.29.0 import dataclasses import datetime import enum diff --git a/examples/src/ondeck/venue.py b/examples/src/ondeck/venue.py index 6159bf6..1911cb3 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.28.0 +# sqlc v1.29.0 # source: venue.sql import dataclasses from typing import AsyncIterator, List, Optional diff --git a/internal/endtoend/endtoend_test.go b/internal/endtoend/endtoend_test.go index bd66c27..09544c1 100644 --- a/internal/endtoend/endtoend_test.go +++ b/internal/endtoend/endtoend_test.go @@ -101,7 +101,7 @@ func TestGenerate(t *testing.T) { cmd.Dir = dir got, err := cmd.CombinedOutput() if diff := cmp.Diff(string(want), string(got)); diff != "" { - t.Errorf("sqlc diff mismatch (-want +got):\n%s", diff) + t.Errorf("sqlc diff mismatch (-want +got):\n%s", got) } if len(want) == 0 && err != nil { t.Error(err) diff --git a/internal/endtoend/testdata/emit_pydantic_models/db/models.py b/internal/endtoend/testdata/emit_pydantic_models/db/models.py index 7676e5c..61ad3eb 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.28.0 +# sqlc v1.29.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 6f5b76f..cc36118 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.28.0 +# sqlc v1.29.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 beae200..6178534 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/__init__.py b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py new file mode 100644 index 0000000..c653489 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py @@ -0,0 +1,9 @@ +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.29.0 +import pydantic + + +class Author(pydantic.BaseModel): + id: int + class: str diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py new file mode 100644 index 0000000..337492e --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py @@ -0,0 +1,44 @@ +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.29.0 +# source: query.sql +from typing import Optional + +import sqlalchemy +import sqlalchemy.ext.asyncio + +from db import models + + +GET_AUTHOR = """-- name: get_author \\:one +SELECT id, class FROM authors +WHERE id = :p1 LIMIT 1 +""" + + +class Querier: + def __init__(self, conn: sqlalchemy.engine.Connection): + self._conn = conn + + def get_author(self, *, id: int) -> Optional[models.Author]: + row = self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id}).first() + if row is None: + return None + return models.Author( + id=row[0], + class=row[1], + ) + + +class AsyncQuerier: + def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection): + self._conn = conn + + async def get_author(self, *, id: int) -> Optional[models.Author]: + row = (await self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id})).first() + if row is None: + return None + return models.Author( + id=row[0], + class=row[1], + ) diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/query.sql b/internal/endtoend/testdata/emit_pydantic_models_with_fields/query.sql new file mode 100644 index 0000000..6c0b1c8 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/query.sql @@ -0,0 +1,3 @@ +-- name: GetAuthor :one +SELECT * FROM authors +WHERE id = $1 LIMIT 1; diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/schema.sql b/internal/endtoend/testdata/emit_pydantic_models_with_fields/schema.sql new file mode 100644 index 0000000..0d611d3 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + class text NOT NULL +); diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml new file mode 100644 index 0000000..6178534 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml @@ -0,0 +1,18 @@ +version: '2' +plugins: +- name: py + wasm: + url: file://../../../../bin/sqlc-gen-python.wasm + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" +sql: +- schema: schema.sql + queries: query.sql + engine: postgresql + codegen: + - plugin: py + out: db + options: + package: db + emit_sync_querier: true + emit_async_querier: true + emit_pydantic_models: true \ No newline at end of file diff --git a/internal/endtoend/testdata/emit_str_enum/db/models.py b/internal/endtoend/testdata/emit_str_enum/db/models.py index 5fdf754..aa43ab1 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.28.0 +# sqlc v1.29.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 8082889..5ea0264 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.28.0 +# sqlc v1.29.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 04e3feb..d1f2b2a 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/exec_result/python/models.py b/internal/endtoend/testdata/exec_result/python/models.py index 034fb2d..6d3e9f5 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.28.0 +# sqlc v1.29.0 import dataclasses diff --git a/internal/endtoend/testdata/exec_result/python/query.py b/internal/endtoend/testdata/exec_result/python/query.py index b68ce39..c9c6e21 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.28.0 +# sqlc v1.29.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 ddffc83..724ba96 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" 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 034fb2d..6d3e9f5 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.28.0 +# sqlc v1.29.0 import dataclasses diff --git a/internal/endtoend/testdata/exec_rows/python/query.py b/internal/endtoend/testdata/exec_rows/python/query.py index 7a9b2a6..a678f3d 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.28.0 +# sqlc v1.29.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 ddffc83..724ba96 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" 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 8ba8803..fc76620 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.28.0 +# sqlc v1.29.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 1e1e161..1fc92fd 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.28.0 +# sqlc v1.29.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 efbb150..126afe4 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" 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 059675d..89c0f8d 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.28.0 +# sqlc v1.29.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 e8b723e..0d9bd97 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.28.0 +# sqlc v1.29.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 336bca7..b371af4 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" 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 30e80db..dc09dab 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.28.0 +# sqlc v1.29.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 5a1fbbc..49b7bd1 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.28.0 +# sqlc v1.29.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 c20cd57..d928aa5 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" 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 059675d..89c0f8d 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.28.0 +# sqlc v1.29.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 47bd6a9..38e0efb 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.28.0 +# sqlc v1.29.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 6e2cdeb..adf3de1 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" 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 c432e4f..25f27f6 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: "d6846ffad948181e611e883cedd2d2be66e091edc1273a0abc6c9da18399e0ca" + sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" sql: - schema: schema.sql queries: query.sql From f92824439ae12b72d107d31b4cffcfcb92cb79f8 Mon Sep 17 00:00:00 2001 From: QuentinN42 Date: Fri, 25 Jul 2025 17:55:11 +0200 Subject: [PATCH 2/5] fix: added reserved python keywords Signed-off-by: QuentinN42 --- .../testdata/emit_pydantic_models/sqlc.yaml | 2 +- .../sqlc.yaml | 2 +- .../endtoend/testdata/emit_str_enum/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 | 81 +++++++++++++++++-- internal/gen_test.go | 53 ++++++++++++ internal/poet/builders.go | 2 +- internal/poet/reserved.go | 38 +++++++++ 14 files changed, 178 insertions(+), 16 deletions(-) create mode 100644 internal/gen_test.go create mode 100644 internal/poet/reserved.go diff --git a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml index 6178534..5cae61b 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml index 6178534..5cae61b 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 d1f2b2a..bb85822 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 724ba96..58de1ac 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 724ba96..58de1ac 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 126afe4..2f60c56 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 b371af4..fc188a5 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 d928aa5..0c0b4d0 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 adf3de1..3147f3c 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" 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 25f27f6..e5692fc 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: "b220b970c2b429b3d3cdde49d2f49c5db73d85c98253ec053533822ab2b58640" + sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" sql: - schema: schema.sql queries: query.sql diff --git a/internal/gen.go b/internal/gen.go index 6e50fae..b99e59a 100644 --- a/internal/gen.go +++ b/internal/gen.go @@ -601,11 +601,82 @@ func pydanticNode(name string) *pyast.ClassDef { } } -func fieldNode(f Field) *pyast.Node { +func fieldNode(f Field, emitPydanticModels bool) *pyast.Node { + if !poet.IsReserved(f.Name) { + return &pyast.Node{ + Node: &pyast.Node_AnnAssign{ + AnnAssign: &pyast.AnnAssign{ + Target: &pyast.Name{Id: f.Name}, + Annotation: f.Type.Annotation(), + Comment: f.Comment, + }, + }, + } + } + + // At this point the field name is a reserved python keyword, so we need to + // update the field name to be a valid python identifier. + if emitPydanticModels { + // On Pydantic add `_` at the end of the field name to make it valid + // Also add a `= pydantic.Field(alias=...)` to the field to allow clean serde + return &pyast.Node{ + Node: &pyast.Node_Assign{ + Assign: &pyast.Assign{ + Targets: []*pyast.Node{ + { + Node: &pyast.Node_AnnAssign{ + AnnAssign: &pyast.AnnAssign{ + Target: &pyast.Name{Id: poet.FieldName(f.Name)}, + Annotation: f.Type.Annotation(), + Comment: f.Comment, + }, + }, + }, + }, + Value: &pyast.Node{ + Node: &pyast.Node_Call{ + Call: &pyast.Call{ + Func: &pyast.Node{ + Node: &pyast.Node_Attribute{ + Attribute: &pyast.Attribute{ + Value: &pyast.Node{ + Node: &pyast.Node_Name{ + Name: &pyast.Name{ + Id: "pydantic", + }, + }, + }, + Attr: "Field", + }, + }, + }, + Keywords: []*pyast.Keyword{ + { + Arg: "alias", + Value: &pyast.Node{ + Node: &pyast.Node_Constant{ + Constant: &pyast.Constant{ + Value: &pyast.Constant_Str{ + Str: f.Name, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + } + + // On dataclasses add `_` at the end of the field name to make it valid return &pyast.Node{ Node: &pyast.Node_AnnAssign{ AnnAssign: &pyast.AnnAssign{ - Target: &pyast.Name{Id: f.Name}, + Target: &pyast.Name{Id: poet.FieldName(f.Name)}, Annotation: f.Type.Annotation(), Comment: f.Comment, }, @@ -731,7 +802,7 @@ func buildModelsTree(ctx *pyTmplCtx, i *importer) *pyast.Node { }) } for _, f := range m.Fields { - def.Body = append(def.Body, fieldNode(f)) + def.Body = append(def.Body, fieldNode(f, ctx.C.EmitPydanticModels)) } mod.Body = append(mod.Body, &pyast.Node{ Node: &pyast.Node_ClassDef{ @@ -857,7 +928,7 @@ func buildQueryTree(ctx *pyTmplCtx, i *importer, source string) *pyast.Node { def = dataclassNode(arg.Struct.Name) } for _, f := range arg.Struct.Fields { - def.Body = append(def.Body, fieldNode(f)) + def.Body = append(def.Body, fieldNode(f, ctx.C.EmitPydanticModels)) } mod.Body = append(mod.Body, poet.Node(def)) } @@ -870,7 +941,7 @@ func buildQueryTree(ctx *pyTmplCtx, i *importer, source string) *pyast.Node { def = dataclassNode(q.Ret.Struct.Name) } for _, f := range q.Ret.Struct.Fields { - def.Body = append(def.Body, fieldNode(f)) + def.Body = append(def.Body, fieldNode(f, ctx.C.EmitPydanticModels)) } mod.Body = append(mod.Body, poet.Node(def)) } diff --git a/internal/gen_test.go b/internal/gen_test.go new file mode 100644 index 0000000..f850eda --- /dev/null +++ b/internal/gen_test.go @@ -0,0 +1,53 @@ +package python + +import ( + "strconv" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/sqlc-dev/sqlc-gen-python/internal/printer" +) + +func Test_fieldNode(t *testing.T) { + cases := []struct { + Expected string + EmitPydanticModels bool + Field Field + }{ + { + Expected: "class_: int", + Field: Field{ + Name: "class", + Type: pyType{ + InnerType: "int", + IsNull: false, + IsArray: false, + }, + }, + EmitPydanticModels: false, + }, + { + Expected: "class_: int = pydantic.Field(\n alias=\"class\",\n)", + Field: Field{ + Name: "class", + Type: pyType{ + InnerType: "int", + IsNull: false, + IsArray: false, + }, + }, + EmitPydanticModels: true, + }, + } + + for _, tc := range cases { + t.Run(tc.Expected+" "+strconv.FormatBool(tc.EmitPydanticModels), func(t *testing.T) { + res := fieldNode(tc.Field, tc.EmitPydanticModels) + result := printer.Print(res, printer.Options{}) + if diff := cmp.Diff(strings.TrimSpace(tc.Expected), strings.TrimSpace(string(result.Python))); diff != "" { + t.Errorf("node to python code mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/internal/poet/builders.go b/internal/poet/builders.go index d38ed7c..4a36606 100644 --- a/internal/poet/builders.go +++ b/internal/poet/builders.go @@ -64,7 +64,7 @@ func Is() *ast.Node { func Name(id string) *ast.Node { return &ast.Node{ Node: &ast.Node_Name{ - Name: &ast.Name{Id: id}, + Name: &ast.Name{Id: FieldName(id)}, }, } } diff --git a/internal/poet/reserved.go b/internal/poet/reserved.go new file mode 100644 index 0000000..d9d3198 --- /dev/null +++ b/internal/poet/reserved.go @@ -0,0 +1,38 @@ +package poet + +import "slices" + +// TODO(quentin@escape.tech): check if this is complete +var reservedKeywords = []string{ + "class", + "if", + "else", + "elif", + "not", + "for", + "and", + "in", + "is", + "or", + "with", + "as", + "assert", + "break", + "except", + "finally", + "try", + "raise", + "return", + "yield", +} + +func IsReserved(name string) bool { + return slices.Contains(reservedKeywords, name) +} + +func FieldName(name string) string { + if IsReserved(name) { + return name + "_" + } + return name +} From 24fcd39f834e82f95563e5e23a31519d7e48bc88 Mon Sep 17 00:00:00 2001 From: QuentinN42 Date: Fri, 25 Jul 2025 18:07:43 +0200 Subject: [PATCH 3/5] refactor: use poet.Node Signed-off-by: QuentinN42 --- .../testdata/emit_pydantic_models/sqlc.yaml | 2 +- .../db/models.py | 4 +- .../db/query.py | 4 +- .../sqlc.yaml | 2 +- .../endtoend/testdata/emit_str_enum/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 | 60 +++++++------------ 13 files changed, 38 insertions(+), 50 deletions(-) diff --git a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml index 5cae61b..1ca3d7c 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py index c653489..353611d 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py @@ -6,4 +6,6 @@ class Author(pydantic.BaseModel): id: int - class: str + class_: str = pydantic.Field( + alias="class", + ) diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py index 337492e..1a0ac38 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py @@ -26,7 +26,7 @@ def get_author(self, *, id: int) -> Optional[models.Author]: return None return models.Author( id=row[0], - class=row[1], + class_=row[1], ) @@ -40,5 +40,5 @@ async def get_author(self, *, id: int) -> Optional[models.Author]: return None return models.Author( id=row[0], - class=row[1], + class_=row[1], ) diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml index 5cae61b..1ca3d7c 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 bb85822..f994e65 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 58de1ac..57290d7 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 58de1ac..57290d7 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 2f60c56..49466ee 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 fc188a5..d58d023 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 0c0b4d0..91d9a96 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 3147f3c..8172f8d 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" 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 e5692fc..6b18de5 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: "30dc4a9deda7f954e6444652e98763b3ad587ea672d88235b2c0f45ba8a4d03b" + sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" sql: - schema: schema.sql queries: query.sql diff --git a/internal/gen.go b/internal/gen.go index b99e59a..63fe590 100644 --- a/internal/gen.go +++ b/internal/gen.go @@ -107,7 +107,7 @@ func (v QueryValue) RowNode(rowVar string) *pyast.Node { } for i, f := range v.Struct.Fields { call.Keywords = append(call.Keywords, &pyast.Keyword{ - Arg: f.Name, + Arg: poet.FieldName(f.Name), Value: subscriptNode( rowVar, constantInt(i), @@ -622,51 +622,37 @@ func fieldNode(f Field, emitPydanticModels bool) *pyast.Node { return &pyast.Node{ Node: &pyast.Node_Assign{ Assign: &pyast.Assign{ - Targets: []*pyast.Node{ - { - Node: &pyast.Node_AnnAssign{ - AnnAssign: &pyast.AnnAssign{ - Target: &pyast.Name{Id: poet.FieldName(f.Name)}, - Annotation: f.Type.Annotation(), - Comment: f.Comment, - }, - }, + Targets: poet.Nodes( + &pyast.AnnAssign{ + Target: &pyast.Name{Id: poet.FieldName(f.Name)}, + Annotation: f.Type.Annotation(), + Comment: f.Comment, }, - }, - Value: &pyast.Node{ - Node: &pyast.Node_Call{ - Call: &pyast.Call{ - Func: &pyast.Node{ - Node: &pyast.Node_Attribute{ - Attribute: &pyast.Attribute{ - Value: &pyast.Node{ - Node: &pyast.Node_Name{ - Name: &pyast.Name{ - Id: "pydantic", - }, - }, - }, - Attr: "Field", - }, - }, - }, - Keywords: []*pyast.Keyword{ - { - Arg: "alias", + ), + Value: poet.Node( + &pyast.Call{ + Func: &pyast.Node{ + Node: &pyast.Node_Attribute{ + Attribute: &pyast.Attribute{ Value: &pyast.Node{ - Node: &pyast.Node_Constant{ - Constant: &pyast.Constant{ - Value: &pyast.Constant_Str{ - Str: f.Name, - }, + Node: &pyast.Node_Name{ + Name: &pyast.Name{ + Id: "pydantic", }, }, }, + Attr: "Field", }, }, }, + Keywords: []*pyast.Keyword{ + { + Arg: "alias", + Value: poet.Constant(f.Name), + }, + }, }, - }, + ), }, }, } From a5d1ee84533fc7db53fb358b3869e91eb80ea756 Mon Sep 17 00:00:00 2001 From: QuentinN42 Date: Fri, 25 Jul 2025 18:38:20 +0200 Subject: [PATCH 4/5] test: added more tests to the poet pkg and generated the pydantic.ConfigDict Signed-off-by: QuentinN42 --- .../emit_pydantic_models/db/models.py | 4 ++ .../testdata/emit_pydantic_models/sqlc.yaml | 2 +- .../db/models.py | 4 ++ .../sqlc.yaml | 2 +- .../endtoend/testdata/emit_str_enum/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 | 39 ++++++++++++++++++ internal/poet/reserved_test.go | 41 +++++++++++++++++++ 14 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 internal/poet/reserved_test.go diff --git a/internal/endtoend/testdata/emit_pydantic_models/db/models.py b/internal/endtoend/testdata/emit_pydantic_models/db/models.py index 61ad3eb..5c6947e 100644 --- a/internal/endtoend/testdata/emit_pydantic_models/db/models.py +++ b/internal/endtoend/testdata/emit_pydantic_models/db/models.py @@ -6,6 +6,10 @@ class Author(pydantic.BaseModel): + model_config = pydantic.ConfigDict( + validate_by_alias=True, + validate_by_name=True, + ) id: int name: str bio: Optional[str] diff --git a/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models/sqlc.yaml index 1ca3d7c..bc03370 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" sql: - schema: schema.sql queries: query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py index 353611d..1403269 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py @@ -5,6 +5,10 @@ class Author(pydantic.BaseModel): + model_config = pydantic.ConfigDict( + validate_by_alias=True, + validate_by_name=True, + ) id: int class_: str = pydantic.Field( alias="class", diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml index 1ca3d7c..bc03370 100644 --- a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml +++ b/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml @@ -3,7 +3,7 @@ plugins: - name: py wasm: url: file://../../../../bin/sqlc-gen-python.wasm - sha256: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 f994e65..1a80fbc 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 57290d7..9c6a7d3 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 57290d7..9c6a7d3 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 49466ee..369271f 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 d58d023..6d7d162 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 91d9a96..4ba6c57 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 8172f8d..4c1abd2 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" 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 6b18de5..270c290 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: "10f4fa000db23558eba8758926bab44a5e50118d3c892ecc4bd64a1fb88f678c" + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" sql: - schema: schema.sql queries: query.sql diff --git a/internal/gen.go b/internal/gen.go index 63fe590..d339650 100644 --- a/internal/gen.go +++ b/internal/gen.go @@ -598,6 +598,45 @@ func pydanticNode(name string) *pyast.ClassDef { }, }, }, + Body: poet.Nodes( + &pyast.Assign{ + Targets: []*pyast.Node{ + { + Node: &pyast.Node_Name{ + Name: &pyast.Name{Id: "model_config"}, + }, + }, + }, + Value: poet.Node( + &pyast.Call{ + Func: &pyast.Node{ + Node: &pyast.Node_Attribute{ + Attribute: &pyast.Attribute{ + Value: &pyast.Node{ + Node: &pyast.Node_Name{ + Name: &pyast.Name{ + Id: "pydantic", + }, + }, + }, + Attr: "ConfigDict", + }, + }, + }, + Keywords: []*pyast.Keyword{ + { + Arg: "validate_by_alias", + Value: poet.Name("True"), + }, + { + Arg: "validate_by_name", + Value: poet.Name("True"), + }, + }, + }, + ), + }, + ), } } diff --git a/internal/poet/reserved_test.go b/internal/poet/reserved_test.go new file mode 100644 index 0000000..3449090 --- /dev/null +++ b/internal/poet/reserved_test.go @@ -0,0 +1,41 @@ +package poet + +import "testing" + +func Test_FieldName_ShouldNotChangeNonReservedKeywords(t *testing.T) { + cases := []string{ + "hello", + "world", + "iff", + "not_reserved", + "class_", + } + + for _, key := range cases { + t.Run(key, func(t *testing.T) { + got := FieldName(key) + if got != key { + t.Errorf("FieldName(%q) = %q, want %q", key, got, key) + } + }) + } +} + +func Test_FieldName_ShouldUdateReservedKeywords(t *testing.T) { + cases := []string{ + "if", + "class", + } + + for _, key := range cases { + t.Run(key, func(t *testing.T) { + if !IsReserved(key) { + t.Errorf("%s should be reserved", key) + } + got := FieldName(key) + if IsReserved(got) { + t.Errorf("FieldName(%s) = %s, should not be reserved", key, got) + } + }) + } +} From 068fd251596b60ba31d51fb8ffd3a5b057413269 Mon Sep 17 00:00:00 2001 From: QuentinN42 Date: Fri, 25 Jul 2025 18:53:01 +0200 Subject: [PATCH 5/5] feat: added dataclasses tests Signed-off-by: QuentinN42 --- .../db/__init__.py | 0 .../db/models.py | 10 +++++ .../db/query.py | 0 .../query.sql | 0 .../schema.sql | 0 .../sqlc.yaml | 18 ++++++++ .../db/__init__.py | 0 .../db/models.py | 0 .../db/query.py | 44 +++++++++++++++++++ .../query.sql | 3 ++ .../schema.sql | 4 ++ .../sqlc.yaml | 0 12 files changed, 79 insertions(+) rename internal/endtoend/testdata/{emit_pydantic_models_with_fields => dataclasses_with_reserved_keywords}/db/__init__.py (100%) create mode 100644 internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py rename internal/endtoend/testdata/{emit_pydantic_models_with_fields => dataclasses_with_reserved_keywords}/db/query.py (100%) rename internal/endtoend/testdata/{emit_pydantic_models_with_fields => dataclasses_with_reserved_keywords}/query.sql (100%) rename internal/endtoend/testdata/{emit_pydantic_models_with_fields => dataclasses_with_reserved_keywords}/schema.sql (100%) create mode 100644 internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/__init__.py rename internal/endtoend/testdata/{emit_pydantic_models_with_fields => emit_pydantic_models_with_reserved_keywords}/db/models.py (100%) create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/query.py create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/query.sql create mode 100644 internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/schema.sql rename internal/endtoend/testdata/{emit_pydantic_models_with_fields => emit_pydantic_models_with_reserved_keywords}/sqlc.yaml (100%) diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/__init__.py b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/__init__.py similarity index 100% rename from internal/endtoend/testdata/emit_pydantic_models_with_fields/db/__init__.py rename to internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/__init__.py diff --git a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py new file mode 100644 index 0000000..f2dd802 --- /dev/null +++ b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/models.py @@ -0,0 +1,10 @@ +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.29.0 +import dataclasses + + +@dataclasses.dataclass() +class Author: + id: int + class_: str diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/query.py similarity index 100% rename from internal/endtoend/testdata/emit_pydantic_models_with_fields/db/query.py rename to internal/endtoend/testdata/dataclasses_with_reserved_keywords/db/query.py diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/query.sql b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/query.sql similarity index 100% rename from internal/endtoend/testdata/emit_pydantic_models_with_fields/query.sql rename to internal/endtoend/testdata/dataclasses_with_reserved_keywords/query.sql diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/schema.sql b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/schema.sql similarity index 100% rename from internal/endtoend/testdata/emit_pydantic_models_with_fields/schema.sql rename to internal/endtoend/testdata/dataclasses_with_reserved_keywords/schema.sql diff --git a/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml new file mode 100644 index 0000000..a7cfc22 --- /dev/null +++ b/internal/endtoend/testdata/dataclasses_with_reserved_keywords/sqlc.yaml @@ -0,0 +1,18 @@ +version: "2" +plugins: + - name: py + wasm: + url: file://../../../../bin/sqlc-gen-python.wasm + sha256: "24b0da217e85c9b952a4c746476aa761e9b293a4a68bef8409d97edc1c003016" +sql: + - schema: schema.sql + queries: query.sql + engine: postgresql + codegen: + - plugin: py + out: db + options: + package: db + emit_sync_querier: true + emit_async_querier: true + emit_pydantic_models: false diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/__init__.py b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/models.py similarity index 100% rename from internal/endtoend/testdata/emit_pydantic_models_with_fields/db/models.py rename to internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/models.py 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 new file mode 100644 index 0000000..1a0ac38 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/db/query.py @@ -0,0 +1,44 @@ +# Code generated by sqlc. DO NOT EDIT. +# versions: +# sqlc v1.29.0 +# source: query.sql +from typing import Optional + +import sqlalchemy +import sqlalchemy.ext.asyncio + +from db import models + + +GET_AUTHOR = """-- name: get_author \\:one +SELECT id, class FROM authors +WHERE id = :p1 LIMIT 1 +""" + + +class Querier: + def __init__(self, conn: sqlalchemy.engine.Connection): + self._conn = conn + + def get_author(self, *, id: int) -> Optional[models.Author]: + row = self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id}).first() + if row is None: + return None + return models.Author( + id=row[0], + class_=row[1], + ) + + +class AsyncQuerier: + def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection): + self._conn = conn + + async def get_author(self, *, id: int) -> Optional[models.Author]: + row = (await self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id})).first() + if row is None: + return None + return models.Author( + id=row[0], + class_=row[1], + ) diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/query.sql b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/query.sql new file mode 100644 index 0000000..6c0b1c8 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/query.sql @@ -0,0 +1,3 @@ +-- name: GetAuthor :one +SELECT * FROM authors +WHERE id = $1 LIMIT 1; diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/schema.sql b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/schema.sql new file mode 100644 index 0000000..0d611d3 --- /dev/null +++ b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + class text NOT NULL +); diff --git a/internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml b/internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml similarity index 100% rename from internal/endtoend/testdata/emit_pydantic_models_with_fields/sqlc.yaml rename to internal/endtoend/testdata/emit_pydantic_models_with_reserved_keywords/sqlc.yaml