Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixed-duplicate-params.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixed
body: Queries mixing a positional reference with a same-named sqlc.arg() no longer generate a duplicate function parameter
time: 2026-06-09T00:00:01.0000000Z
custom:
Author: Mic92
PR: "164"
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixed-field-singularization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixed
body: Column field names are no longer singularized (`outputs` generated an `output` field); duplicate selected columns get suffixed fields instead of an invalid class
time: 2026-06-09T00:00:00.0000000Z
custom:
Author: Mic92
PR: "164"
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixed-queryresults-sequence.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixed
body: QueryResultsArgsType includes Sequence so array parameters of :many queries type-check
time: 2026-06-09T00:00:02.0000000Z
custom:
Author: Mic92
PR: "164"
32 changes: 27 additions & 5 deletions internal/builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,19 @@ func (gen *PythonGenerator) buildQueries(tables []core.Table) ([]core.Query, err
}}
} else if len(query.Params) >= 1 {
var values []core.QueryValue
// Positional ($n) and named (sqlc.arg) references
// can infer the same name; suffix duplicates to keep
// the function definition valid.
seenParams := map[string]int{}
for _, p := range query.Params {
baseName := core.Escape(core.ParamName(p))
name := baseName
if n := seenParams[baseName]; n > 0 {
name = fmt.Sprintf("%s_%d", baseName, n+1)
}
seenParams[baseName]++
values = append(values, core.QueryValue{
Name: core.Escape(core.ParamName(p)),
Name: name,
DBName: p.Column.GetName(),
Typ: gen.makePythonType(p.Column),
Column: p.Column,
Expand Down Expand Up @@ -370,11 +380,23 @@ func (gen *PythonGenerator) columnsToStruct(name string, columns []goColumn, use
fieldName = fmt.Sprintf("%s_%d", fieldName, suffix)
}

f := core.Column{
Name: inflection.Singular(inflection.SingularParams{
Name: core.ColumnName(c.Column, i),
// Singularizing belongs to table names only; on columns it
// renames e.g. "outputs" to "output". Embedded fields are
// singularized: they hold one row of the joined table.
// Duplicate columns need the suffix in the field name,
// otherwise the class ends up with duplicate fields.
pyFieldName := core.ColumnName(c.Column, i)
if c.embed != nil {
pyFieldName = inflection.Singular(inflection.SingularParams{
Name: pyFieldName,
Exclusions: gen.config.InflectionExcludeTableNames,
}),
})
}
if suffix > 0 {
pyFieldName = fmt.Sprintf("%s_%d", pyFieldName, suffix)
}
f := core.Column{
Name: pyFieldName,
DBName: colName,
Column: c.Column,
}
Expand Down
4 changes: 3 additions & 1 deletion internal/core/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ func (i *Importer) queryImports(fileName string) ([]string, []string, []string)
if IsInMultipleMaps("datetime", std, typeCheck) {
queryResultsArgsType += " | datetime.date | datetime.time | datetime.datetime | datetime.timedelta"
}
queryResultsArgsType += " | None"
// asyncpg passes array-typed parameters (e.g. text[]) as
// sequences.
queryResultsArgsType += " | collections.abc.Sequence[typing.Any] | None"
typeLines = append(typeLines, queryResultsArgsType)
}

Expand Down
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/attrs/classes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/attrs/classes/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

Expand Down
6 changes: 3 additions & 3 deletions test/driver_aiosqlite/attrs/classes/queries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing queries from file queries.sql."""
from __future__ import annotations

Expand All @@ -22,7 +22,7 @@
import collections.abc
import sqlite3

QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | None
QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | collections.abc.Sequence[typing.Any] | None

from test.driver_aiosqlite.attrs.classes import models

Expand Down
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/attrs/functions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/attrs/functions/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

Expand Down
6 changes: 3 additions & 3 deletions test/driver_aiosqlite/attrs/functions/queries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing queries from file queries.sql."""
from __future__ import annotations

Expand Down Expand Up @@ -59,7 +59,7 @@
import collections.abc
import sqlite3

QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | None
QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | collections.abc.Sequence[typing.Any] | None

from test.driver_aiosqlite.attrs.functions import models

Expand Down
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/dataclass/classes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/dataclass/classes/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

Expand Down
6 changes: 3 additions & 3 deletions test/driver_aiosqlite/dataclass/classes/queries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing queries from file queries.sql."""
from __future__ import annotations

Expand All @@ -21,7 +21,7 @@
import collections.abc
import sqlite3

QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | None
QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | collections.abc.Sequence[typing.Any] | None

from test.driver_aiosqlite.dataclass.classes import models

Expand Down
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/dataclass/functions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/dataclass/functions/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

Expand Down
6 changes: 3 additions & 3 deletions test/driver_aiosqlite/dataclass/functions/queries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing queries from file queries.sql."""
from __future__ import annotations

Expand Down Expand Up @@ -59,7 +59,7 @@
import collections.abc
import sqlite3

QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | None
QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | collections.abc.Sequence[typing.Any] | None

from test.driver_aiosqlite.dataclass.functions import models

Expand Down
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/msgspec/classes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/msgspec/classes/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

Expand Down
6 changes: 3 additions & 3 deletions test/driver_aiosqlite/msgspec/classes/queries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing queries from file queries.sql."""
from __future__ import annotations

Expand All @@ -21,7 +21,7 @@
import collections.abc
import sqlite3

QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | None
QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | collections.abc.Sequence[typing.Any] | None

from test.driver_aiosqlite.msgspec.classes import models

Expand Down
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/msgspec/functions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
4 changes: 2 additions & 2 deletions test/driver_aiosqlite/msgspec/functions/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

Expand Down
6 changes: 3 additions & 3 deletions test/driver_aiosqlite/msgspec/functions/queries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing queries from file queries.sql."""
from __future__ import annotations

Expand Down Expand Up @@ -59,7 +59,7 @@
import collections.abc
import sqlite3

QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | None
QueryResultsArgsType: typing.TypeAlias = int | float | str | memoryview | decimal.Decimal | datetime.date | datetime.time | datetime.datetime | datetime.timedelta | collections.abc.Sequence[typing.Any] | None

from test.driver_aiosqlite.msgspec.functions import models

Expand Down
Binary file modified test/driver_aiosqlite/sqlc-gen-better-python.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion test/driver_aiosqlite/sqlc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins:
- name: python
wasm:
url: file://sqlc-gen-better-python.wasm
sha256: ee7bd0c07b784b80ea8c5853d9a6a04c51a7abbfd2663f470e9a5d2f623b967e
sha256: 53c4de16a585391d2ff2a545b12d04bce82b6e194873042706d471d343f2bbc2
sql:
- schema: schema.sql
queries: queries.sql
Expand Down
4 changes: 2 additions & 2 deletions test/driver_asyncpg/attrs/classes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Package containing queries and models automatically generated using sqlc-gen-better-python."""
22 changes: 20 additions & 2 deletions test/driver_asyncpg/attrs/classes/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.30.0
# sqlc-gen-better-python v0.4.4
# sqlc v1.31.1
# sqlc-gen-better-python v0.4.5
"""Module containing models."""
from __future__ import annotations

__all__: collections.abc.Sequence[str] = (
"TestFieldNaming",
"TestInnerPostgresType",
"TestPostgresType",
"TestTypeOverride",
Expand All @@ -22,6 +23,23 @@
import uuid


@attrs.define()
class TestFieldNaming:
"""Model representing TestFieldNaming.

Attributes
----------
id : int
outputs : str
groups : collections.abc.Sequence[str]

"""

id: int
outputs: str
groups: collections.abc.Sequence[str]


@attrs.define()
class TestInnerPostgresType:
"""Model representing TestInnerPostgresType.
Expand Down
Loading