Skip to content

Commit 0806323

Browse files
committed
add config option to control if have schema prefix for types or not
1 parent 266fab8 commit 0806323

File tree

4 files changed

+90
-24
lines changed

4 files changed

+90
-24
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@ sql:
2020
emit_async_querier: true
2121
```
2222
23+
### Configuration Options
24+
25+
These are the supported `options` for the `py` plugin. Add them under the `codegen[].options` section of your `sqlc.yaml`.
26+
27+
- package: Module path used for imports in generated query files (e.g., `from <package> import models`).
28+
- emit_sync_querier: Emit a synchronous `Querier` class using `sqlalchemy.engine.Connection`.
29+
- emit_async_querier: Emit an asynchronous `AsyncQuerier` class using `sqlalchemy.ext.asyncio.AsyncConnection`.
30+
- emit_pydantic_models: Emit Pydantic models instead of `dataclasses` for models.py. See the section below.
31+
- emit_str_enum: Emit enums as `enum.StrEnum` (Python >=3.11). When false, emit `(str, enum.Enum)`. See the section below.
32+
- emit_schema_name_prefix: When true, prefix non-default schema to generated types to avoid name collisions. Examples:
33+
- false (default): `Book`, `BookStatus`
34+
- true: `MySchemaBook`, `MySchemaBookStatus` when the objects live in schema `my_schema`.
35+
- emit_exact_table_names: When true, do not singularize table names for model class names.
36+
- query_parameter_limit: Integer controlling when query params are grouped into a single struct argument.
37+
- If the number of parameters exceeds this value, a single `Params` struct is emitted.
38+
- Set to 0 to always emit a struct; omit or set to a large value to keep separate parameters.
39+
- inflection_exclude_table_names: A list of table names to exclude from singularization when `emit_exact_table_names` is false.
40+
- overrides: Column type overrides; see the section below.
41+
42+
Notes
43+
- out: Controlled by `codegen[].out` at the sqlc level. The plugin’s `out` option is not used; prefer the top-level `out` value.
44+
45+
2346
### Emit Pydantic Models instead of `dataclasses`
2447

2548
Option: `emit_pydantic_models`

internal/config.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
package python
22

3+
type OverrideColumn struct {
4+
Column string `json:"column"`
5+
PyType string `json:"py_type"`
6+
PyImport string `json:"py_import"`
7+
}
8+
39
type Config struct {
4-
EmitExactTableNames bool `json:"emit_exact_table_names"`
5-
EmitSyncQuerier bool `json:"emit_sync_querier"`
6-
EmitAsyncQuerier bool `json:"emit_async_querier"`
7-
Package string `json:"package"`
8-
Out string `json:"out"`
9-
EmitPydanticModels bool `json:"emit_pydantic_models"`
10-
EmitStrEnum bool `json:"emit_str_enum"`
11-
QueryParameterLimit *int32 `json:"query_parameter_limit"`
12-
InflectionExcludeTableNames []string `json:"inflection_exclude_table_names"`
10+
EmitExactTableNames bool `json:"emit_exact_table_names"`
11+
EmitSyncQuerier bool `json:"emit_sync_querier"`
12+
EmitAsyncQuerier bool `json:"emit_async_querier"`
13+
Package string `json:"package"`
14+
Out string `json:"out"`
15+
EmitPydanticModels bool `json:"emit_pydantic_models"`
16+
EmitStrEnum bool `json:"emit_str_enum"`
17+
EmitSchemaNamePrefix bool `json:"emit_schema_name_prefix"`
18+
QueryParameterLimit *int32 `json:"query_parameter_limit"`
19+
InflectionExcludeTableNames []string `json:"inflection_exclude_table_names"`
20+
Overrides []OverrideColumn `json:"overrides"`
1321
}

internal/gen.go

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,18 +181,52 @@ func (q Query) ArgDictNode() *pyast.Node {
181181
}
182182

183183
func makePyType(req *plugin.GenerateRequest, col *plugin.Column) pyType {
184-
typ := pyInnerType(req, col)
184+
// Parse the configuration
185+
var conf Config
186+
if len(req.PluginOptions) > 0 {
187+
if err := json.Unmarshal(req.PluginOptions, &conf); err != nil {
188+
log.Printf("failed to parse plugin options: %s", err)
189+
}
190+
}
191+
192+
// Check for overrides
193+
if len(conf.Overrides) > 0 && col.Table != nil {
194+
tableName := col.Table.Name
195+
if col.Table.Schema != "" && col.Table.Schema != req.Catalog.DefaultSchema {
196+
tableName = col.Table.Schema + "." + tableName
197+
}
198+
199+
// Look for a matching override
200+
for _, override := range conf.Overrides {
201+
overrideKey := tableName + "." + col.Name
202+
if override.Column == overrideKey {
203+
// Found a match, use the override
204+
typeStr := override.PyType
205+
if override.PyImport != "" && !strings.Contains(typeStr, ".") {
206+
typeStr = override.PyImport + "." + override.PyType
207+
}
208+
return pyType{
209+
InnerType: typeStr,
210+
IsArray: col.IsArray,
211+
IsNull: !col.NotNull,
212+
}
213+
}
214+
}
215+
}
216+
217+
// No override found, use the standard type mapping
218+
typ := pyInnerType(conf, req, col)
185219
return pyType{
186220
InnerType: typ,
187221
IsArray: col.IsArray,
188222
IsNull: !col.NotNull,
189223
}
190224
}
191225

192-
func pyInnerType(req *plugin.GenerateRequest, col *plugin.Column) string {
226+
func pyInnerType(conf Config, req *plugin.GenerateRequest, col *plugin.Column) string {
193227
switch req.Settings.Engine {
194228
case "postgresql":
195-
return postgresType(req, col)
229+
return postgresType(conf, req, col)
196230
default:
197231
log.Println("unsupported engine type")
198232
return "Any"
@@ -226,18 +260,18 @@ func pyEnumValueName(value string) string {
226260
return strings.ToUpper(id)
227261
}
228262

229-
func buildEnums(req *plugin.GenerateRequest) []Enum {
263+
func buildEnums(conf Config, req *plugin.GenerateRequest) []Enum {
230264
var enums []Enum
231265
for _, schema := range req.Catalog.Schemas {
232266
if schema.Name == "pg_catalog" || schema.Name == "information_schema" {
233267
continue
234268
}
235269
for _, enum := range schema.Enums {
236270
var enumName string
237-
if schema.Name == req.Catalog.DefaultSchema {
238-
enumName = enum.Name
239-
} else {
271+
if conf.EmitSchemaNamePrefix && schema.Name != req.Catalog.DefaultSchema {
240272
enumName = schema.Name + "_" + enum.Name
273+
} else {
274+
enumName = enum.Name
241275
}
242276
e := Enum{
243277
Name: modelName(enumName, req.Settings),
@@ -267,10 +301,10 @@ func buildModels(conf Config, req *plugin.GenerateRequest) []Struct {
267301
}
268302
for _, table := range schema.Tables {
269303
var tableName string
270-
if schema.Name == req.Catalog.DefaultSchema {
271-
tableName = table.Rel.Name
272-
} else {
304+
if conf.EmitSchemaNamePrefix && schema.Name != req.Catalog.DefaultSchema {
273305
tableName = schema.Name + "_" + table.Rel.Name
306+
} else {
307+
tableName = table.Rel.Name
274308
}
275309
structName := tableName
276310
if !conf.EmitExactTableNames {
@@ -1185,7 +1219,7 @@ func Generate(_ context.Context, req *plugin.GenerateRequest) (*plugin.GenerateR
11851219
}
11861220
}
11871221

1188-
enums := buildEnums(req)
1222+
enums := buildEnums(conf, req)
11891223
models := buildModels(conf, req)
11901224
queries, err := buildQueries(conf, req, models)
11911225
if err != nil {

internal/postgresql_type.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/sqlc-dev/plugin-sdk-go/sdk"
88
)
99

10-
func postgresType(req *plugin.GenerateRequest, col *plugin.Column) string {
10+
func postgresType(conf Config, req *plugin.GenerateRequest, col *plugin.Column) string {
1111
columnType := sdk.DataType(col.Type)
1212

1313
switch columnType {
@@ -50,10 +50,11 @@ func postgresType(req *plugin.GenerateRequest, col *plugin.Column) string {
5050
for _, enum := range schema.Enums {
5151
// Match both unqualified and schema-qualified enum type names
5252
if columnType == enum.Name || columnType == schema.Name+"."+enum.Name {
53-
if schema.Name == req.Catalog.DefaultSchema {
54-
return "models." + modelName(enum.Name, req.Settings)
53+
name := enum.Name
54+
if conf.EmitSchemaNamePrefix && schema.Name != req.Catalog.DefaultSchema {
55+
name = schema.Name + "_" + enum.Name
5556
}
56-
return "models." + modelName(schema.Name+"_"+enum.Name, req.Settings)
57+
return "models." + modelName(name, req.Settings)
5758
}
5859
}
5960
}

0 commit comments

Comments
 (0)