Skip to content

Commit bfa71a9

Browse files
committed
feat: added output_models_file_name and output_querier_file options to configure output files
1 parent ba256bd commit bfa71a9

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# README
12
## Usage
23

34
```yaml
@@ -20,3 +21,13 @@ sql:
2021
emit_generators: true
2122
emit_async: false
2223
```
24+
25+
## Multiple packages
26+
If you have have a mono-repository setup you may want to split the output of queries and models. You can achieve this by using the `output_models_file_name`
27+
and `output_querier_file` fields. If `output_models_file_name` is set to `null` for it will not output the `models.py` file. Setting `output_querier_file` to false will prevent outputting any query files. Combining these you can set one codegen to only output models while the other codegen outputs only queries. Make sure the `package` configuration is set equally so the query files import correctly the models.
28+
29+
SQLC needs at least one query, so you may need to add a unused query like the following in your schema and reuse the `schema` as `queries`.
30+
```sql
31+
-- name: Skip :one
32+
SELECT 1;
33+
```

internal/config.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package python
22

3+
// TODO: Where are these properly documented?
34
type Config struct {
4-
EmitModule bool `json:"emit_module"` // If true emits functions in module, else wraps in a class.
5-
EmitGenerators bool `json:"emit_generators"` // Will we use generators or lists, defaults to true
6-
EmitAsync bool `json:"emit_async"` // Emits async code instead of sync
5+
EmitAsync bool `json:"emit_async"` // Emits async code instead of sync
76
EmitExactTableNames bool `json:"emit_exact_table_names"`
7+
EmitGenerators bool `json:"emit_generators"` // Will we use generators or lists, defaults to true
8+
EmitModule bool `json:"emit_module"` // If true emits functions in module, else wraps in a class.
9+
EmitPydanticModels bool `json:"emit_pydantic_models"`
810
EmitSyncQuerier bool `json:"emit_sync_querier"` // DEPRECATED ALIAS FOR: emit_type = 'class', emit_generators = True
911
EmitAsyncQuerier bool `json:"emit_async_querier"` // DEPRECATED ALIAS FOR: emit_type = 'class', emit_generators = True
10-
Package string `json:"package"`
12+
InflectionExcludeTableNames []string `json:"inflection_exclude_table_names"`
1113
Out string `json:"out"`
12-
EmitPydanticModels bool `json:"emit_pydantic_models"`
14+
OutputModelsFileName *string `json:"output_models_file_name,omitempty"` // Can be string or null to exclude generating models file
15+
OutputQuerierFile bool `json:"output_querier_file,omitempty"` // Skips outputting queries
16+
Package string `json:"package"`
1317
QueryParameterLimit *int32 `json:"query_parameter_limit"`
14-
InflectionExcludeTableNames []string `json:"inflection_exclude_table_names"`
1518
}

internal/gen.go

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,13 @@ func HashComment(s string) string {
10471047
}
10481048

10491049
func Generate(_ context.Context, req *plugin.CodeGenRequest) (*plugin.CodeGenResponse, error) {
1050-
var conf Config
1050+
// Setup our defaults for our Config struct and parse our config file
1051+
defaultModelsFileName := "models.py"
1052+
conf := Config{
1053+
OutputModelsFileName: &defaultModelsFileName,
1054+
OutputQuerierFile: true,
1055+
}
1056+
10511057
if len(req.PluginOptions) > 0 {
10521058
if err := json.Unmarshal(req.PluginOptions, &conf); err != nil {
10531059
return nil, err
@@ -1086,26 +1092,34 @@ func Generate(_ context.Context, req *plugin.CodeGenRequest) (*plugin.CodeGenRes
10861092
}
10871093

10881094
output := map[string]string{}
1089-
result := pyprint.Print(buildModelsTree(&tctx, i), pyprint.Options{})
1090-
tctx.SourceName = "models.py"
1091-
output["models.py"] = string(result.Python)
10921095

1093-
files := map[string]struct{}{}
1094-
for _, q := range queries {
1095-
files[q.SourceName] = struct{}{}
1096+
// Generate the model file.
1097+
if conf.OutputModelsFileName != nil {
1098+
result := pyprint.Print(buildModelsTree(&tctx, i), pyprint.Options{})
1099+
tctx.SourceName = *conf.OutputModelsFileName
1100+
output[*conf.OutputModelsFileName] = string(result.Python)
10961101
}
10971102

1098-
for source := range files {
1099-
tctx.SourceName = source
1100-
result := pyprint.Print(buildQueryTree(&tctx, i, source), pyprint.Options{})
1101-
name := source
1102-
if !strings.HasSuffix(name, ".py") {
1103-
name = strings.TrimSuffix(name, ".sql")
1104-
name += ".py"
1103+
// Generate for each .sql file a corresponding Python query file.
1104+
if conf.OutputQuerierFile {
1105+
files := map[string]struct{}{}
1106+
for _, q := range queries {
1107+
files[q.SourceName] = struct{}{}
1108+
}
1109+
1110+
for source := range files {
1111+
tctx.SourceName = source
1112+
result := pyprint.Print(buildQueryTree(&tctx, i, source), pyprint.Options{})
1113+
name := source
1114+
if !strings.HasSuffix(name, ".py") {
1115+
name = strings.TrimSuffix(name, ".sql")
1116+
name += ".py"
1117+
}
1118+
output[name] = string(result.Python)
11051119
}
1106-
output[name] = string(result.Python)
11071120
}
11081121

1122+
// Finally we send our outputs back to SQLC
11091123
resp := plugin.CodeGenResponse{}
11101124

11111125
for filename, code := range output {

0 commit comments

Comments
 (0)