无法从gqlgen-sqlboiler生成generated_sort.go文件。

huangapple go评论83阅读模式
英文:

not able to generate generated_sort.go from gqlgen-sqlboiler

问题

我正在使用的是以下版本的库:

  • sqlboiler 版本:v4.14.2
  • gqlgen 版本:v0.17.33
  • gqlgen-sqlboiler 版本:v3.3.12

根据你提供的信息,你在运行 convert.go 时遇到了错误。以下是 convert.go 的代码:

package main

import (
	"github.com/99designs/gqlgen/codegen/config"
	"github.com/rs/zerolog/log"
	gbgen "github.com/web-ridge/gqlgen-sqlboiler/v3"
	"github.com/web-ridge/gqlgen-sqlboiler/v3/cache"
	"github.com/web-ridge/gqlgen-sqlboiler/v3/structs"
	"os"
	"os/exec"
	"strings"
)

func main() {
	// 将工作目录更改为包含所有配置文件的父目录
	newDir, _ := os.Getwd()
	os.Chdir(strings.TrimSuffix(newDir, "/convert"))

	enableSoftDeletes := true
	boilerArgs := []string{"mysql", "--no-back-referencing", "--wipe", "-d"}
	if enableSoftDeletes {
		boilerArgs = append(boilerArgs, "--add-soft-deletes")
	}
	cmd := exec.Command("sqlboiler", boilerArgs...)

	err := cmd.Run()
	if err != nil {
		log.Fatal().Err(err).Str("command", cmd.String()).Msg("error generating dm models running sql-boiler")
	}

	output := structs.Config{
		Directory:   "helpers", // 支持根目录或子目录
		PackageName: "helpers",
	}
	backend := structs.Config{
		Directory:   "models",
		PackageName: "models",
	}
	frontend := structs.Config{
		Directory:   "models",
		PackageName: "models",
	}

	boilerCache := cache.InitializeBoilerCache(backend)

	generateSchema := true
	generatedSchema := !generateSchema
	if generateSchema {
		if err := gbgen.SchemaWrite(
			gbgen.SchemaConfig{
				BoilerCache:         boilerCache,
				Directives:          []string{"isAuthenticated"},
				SkipInputFields:     []string{"createdAt", "updatedAt", "deletedAt"},
				GenerateMutations:   true,
				GenerateBatchCreate: false,
				GenerateBatchDelete: false,
				GenerateBatchUpdate: false,
				HookShouldAddModel: func(model gbgen.SchemaModel) bool {
					if model.Name == "Config" {
						return false
					}
					return true
				},
				HookChangeFields: func(model *gbgen.SchemaModel, fields []*gbgen.SchemaField, parenType gbgen.ParentType) []*gbgen.SchemaField {
					// profile: UserPayload! @isAuthenticated

					return fields
				},
				HookChangeField: func(model *gbgen.SchemaModel, field *gbgen.SchemaField) {
					// "userId", "userOrganizationId",
					if field.Name == "userId" && model.Name != "UserUserOrganization" {
						field.SkipInput = true
					}
					if field.Name == "userOrganizationId" && model.Name != "UserUserOrganization" {
						field.SkipInput = true
					}
				},
			},
			"../schema.graphql",
			gbgen.SchemaGenerateConfig{
				MergeSchema: false,
			},
		); err != nil {
			log.Fatal().Err(err).Msg("error generating schema")
		}
		generatedSchema = true
	}
	if generatedSchema {

		cfg, err := config.LoadConfigFromDefaultLocations()
		if err != nil {
			log.Fatal().Err(err).Msg("error loading config")
		}

		data, err := gbgen.NewModelPlugin().GenerateCode(cfg)
		if err != nil {
			log.Fatal().Err(err).Msg("error generating graphql models using gqlgen")
		}

		modelCache := cache.InitializeModelCache(cfg, boilerCache, output, backend, frontend)

		if err := gbgen.NewConvertPlugin(
			modelCache,
			gbgen.ConvertPluginConfig{
				DatabaseDriver: gbgen.MySQL,
				//Searchable: {
				//	Company: {
				//		Column: dm.CompanyColumns.Name
				//	},
				//},
			},
		).GenerateCode(); err != nil {
			log.Fatal().Err(err).Msg("error while generating convert/filters")
		}

		if err := gbgen.NewResolverPlugin(
			config.ResolverConfig{
				Filename: "resolvers/all_generated_resolvers.go",
				Package:  "resolvers",
				Type:     "Resolver",
			},
			output,
			boilerCache,
			modelCache,
			gbgen.ResolverPluginConfig{

				EnableSoftDeletes: enableSoftDeletes,
				// Authorization scopes can be used to override e.g. userId, organizationId, tenantId
				// This will be resolved used the provided ScopeResolverName if the result of the AddTrigger=true
				// You would need this if you don't want to require these fields in your schema but you want to add them
				// to the db model.
				// If you do have these fields in your schema but want them authorized you could use a gqlgen directive
				AuthorizationScopes: []*gbgen.AuthorizationScope{},
				// 	{
				// 		ImportPath:        "github.com/my-repo/app/backend/auth",
				// 		ImportAlias:       "auth",
				// 		ScopeResolverName: "UserIDFromContext", // function which is called with the context of the resolver
				// 		BoilerColumnName:  "UserID",
				// 		AddHook: func(model *gbgen.BoilerModel, resolver *gbgen.Resolver, templateKey string) bool {
				// 			// fmt.Println(model.Name)
				// 			// fmt.Println(templateKey)
				// 			// templateKey contains a unique where the resolver tries to add something
				// 			// e.g.
				// 			// most of the time you can ignore this

				// 			// we want the delete call to work for every object we don't want to take in account te user-id here
				// 			if resolver.IsDelete {
				// 				return false
				// 			}

				// 			var addResolver bool
				// 			for _, field := range model.Fields {
				// 				if field.Name == "UserID" {
				// 					addResolver = true
				// 				}
				// 			}
				// 			return addResolver
				// 		},
				// 	},
				// 	{
				// 		ImportPath:        "github.com/my-repo/app/backend/auth",
				// 		ImportAlias:       "auth",
				// 		ScopeResolverName: "UserOrganizationIDFromContext", // function which is called with the context of the resolver
				// 		BoilerColumnName:  "UserOrganizationID",

				// 		AddHook: func(model *gbgen.BoilerModel, resolver *gbgen.Resolver, templateKey string) bool {
				// 			// fmt.Println(model.Name)
				// 			// fmt.Println(templateKey)
				// 			// templateKey contains a unique where the resolver tries to add something
				// 			// e.g.
				// 			// most of the time you can ignore this
				// 			var addResolver bool
				// 			for _, field := range model.Fields {
				// 				if field.Name == "UserOrganizationID" {
				// 					addResolver = true
				// 				}
				// 			}
				// 			return addResolver
				// 		},
				// 	},
				// },
			},
		).GenerateCode(data); err != nil {
			log.Fatal().Err(err).Msg("error while generating resolvers")
		}

	}
}

根据日志,你遇到了以下错误:

4:10PM ERR could not parse golang file error="src.go:1:1: expected 'package', found 'EOF'"
4:10PM ERR error while rendering generated_sort.gotpl error="errors while writing template to helpers/generated_sort.go writeError: <nil>, contentError: execute: template: :44:17: executing "" at <$field.Enum.Name>: nil pointer evaluating *structs.Enum.Name, importError: helpers/generated_sort.go:1:1: expected 'package', found 'EOF'"
4:10PM ERR could not parse golang file error="src.go:1:1: expected 'package', found 'EOF'"
4:10PM ERR could not close file error="invalid argument" fileName=resolvers/all_generated_resolvers.go
4:10PM FTL error while generating resolvers error="errors while printing template to resolvers/all_generated_resolvers.go  invalid argument"
exit status 1

请问你需要什么样的帮助来解决这个问题?

英文:

I am using
sqlboiler version: v4.14.2
gqlgen version: v0.17.33
gqlgen-sqlboiler version : v3.3.12
https://github.com/web-ridge/gqlgen-sqlboiler

After following readme.md pre requisite getting following error while running convert.go
following is convert.go

package main
import (
&quot;github.com/99designs/gqlgen/codegen/config&quot;
&quot;github.com/rs/zerolog/log&quot;
gbgen &quot;github.com/web-ridge/gqlgen-sqlboiler/v3&quot;
&quot;github.com/web-ridge/gqlgen-sqlboiler/v3/cache&quot;
&quot;github.com/web-ridge/gqlgen-sqlboiler/v3/structs&quot;
&quot;os&quot;
&quot;os/exec&quot;
&quot;strings&quot;
)
func main() {
// change working directory to parent directory where all configs are located
newDir, _ := os.Getwd()
os.Chdir(strings.TrimSuffix(newDir, &quot;/convert&quot;))
enableSoftDeletes := true
boilerArgs := []string{&quot;mysql&quot;, &quot;--no-back-referencing&quot;, &quot;--wipe&quot;, &quot;-d&quot;}
if enableSoftDeletes {
boilerArgs = append(boilerArgs, &quot;--add-soft-deletes&quot;)
}
cmd := exec.Command(&quot;sqlboiler&quot;, boilerArgs...)
err := cmd.Run()
if err != nil {
log.Fatal().Err(err).Str(&quot;command&quot;, cmd.String()).Msg(&quot;error generating dm models running sql-boiler&quot;)
}
output := structs.Config{
Directory:   &quot;helpers&quot;, // supports root or sub directories
PackageName: &quot;helpers&quot;,
}
backend := structs.Config{
Directory:   &quot;models&quot;,
PackageName: &quot;models&quot;,
}
frontend := structs.Config{
Directory:   &quot;models&quot;,
PackageName: &quot;models&quot;,
}
boilerCache := cache.InitializeBoilerCache(backend)
generateSchema := true
generatedSchema := !generateSchema
if generateSchema {
if err := gbgen.SchemaWrite(
gbgen.SchemaConfig{
BoilerCache:         boilerCache,
Directives:          []string{&quot;isAuthenticated&quot;},
SkipInputFields:     []string{&quot;createdAt&quot;, &quot;updatedAt&quot;, &quot;deletedAt&quot;},
GenerateMutations:   true,
GenerateBatchCreate: false,
GenerateBatchDelete: false,
GenerateBatchUpdate: false,
HookShouldAddModel: func(model gbgen.SchemaModel) bool {
if model.Name == &quot;Config&quot; {
return false
}
return true
},
HookChangeFields: func(model *gbgen.SchemaModel, fields []*gbgen.SchemaField, parenType gbgen.ParentType) []*gbgen.SchemaField {
//profile: UserPayload! @isAuthenticated
return fields
},
HookChangeField: func(model *gbgen.SchemaModel, field *gbgen.SchemaField) {
//&quot;userId&quot;, &quot;userOrganizationId&quot;,
if field.Name == &quot;userId&quot; &amp;&amp; model.Name != &quot;UserUserOrganization&quot; {
field.SkipInput = true
}
if field.Name == &quot;userOrganizationId&quot; &amp;&amp; model.Name != &quot;UserUserOrganization&quot; {
field.SkipInput = true
}
},
},
&quot;../schema.graphql&quot;,
gbgen.SchemaGenerateConfig{
MergeSchema: false,
},
); err != nil {
log.Fatal().Err(err).Msg(&quot;error generating schema&quot;)
}
generatedSchema = true
}
if generatedSchema {
cfg, err := config.LoadConfigFromDefaultLocations()
if err != nil {
log.Fatal().Err(err).Msg(&quot;error loading config&quot;)
}
data, err := gbgen.NewModelPlugin().GenerateCode(cfg)
if err != nil {
log.Fatal().Err(err).Msg(&quot;error generating graphql models using gqlgen&quot;)
}
modelCache := cache.InitializeModelCache(cfg, boilerCache, output, backend, frontend)
if err := gbgen.NewConvertPlugin(
modelCache,
gbgen.ConvertPluginConfig{
DatabaseDriver: gbgen.MySQL,
//Searchable: {
//	Company: {
//		Column: dm.CompanyColumns.Name
//	},
//},
},
).GenerateCode(); err != nil {
log.Fatal().Err(err).Msg(&quot;error while generating convert/filters&quot;)
}
if err := gbgen.NewResolverPlugin(
config.ResolverConfig{
Filename: &quot;resolvers/all_generated_resolvers.go&quot;,
Package:  &quot;resolvers&quot;,
Type:     &quot;Resolver&quot;,
},
output,
boilerCache,
modelCache,
gbgen.ResolverPluginConfig{
EnableSoftDeletes: enableSoftDeletes,
// Authorization scopes can be used to override e.g. userId, organizationId, tenantId
// This will be resolved used the provided ScopeResolverName if the result of the AddTrigger=true
// You would need this if you don&#39;t want to require these fields in your schema but you want to add them
// to the db model.
// If you do have these fields in your schema but want them authorized you could use a gqlgen directive
AuthorizationScopes: []*gbgen.AuthorizationScope{},
// 	{
// 		ImportPath:        &quot;github.com/my-repo/app/backend/auth&quot;,
// 		ImportAlias:       &quot;auth&quot;,
// 		ScopeResolverName: &quot;UserIDFromContext&quot;, // function which is called with the context of the resolver
// 		BoilerColumnName:  &quot;UserID&quot;,
// 		AddHook: func(model *gbgen.BoilerModel, resolver *gbgen.Resolver, templateKey string) bool {
// 			// fmt.Println(model.Name)
// 			// fmt.Println(templateKey)
// 			// templateKey contains a unique where the resolver tries to add something
// 			// e.g.
// 			// most of the time you can ignore this
// 			// we want the delete call to work for every object we don&#39;t want to take in account te user-id here
// 			if resolver.IsDelete {
// 				return false
// 			}
// 			var addResolver bool
// 			for _, field := range model.Fields {
// 				if field.Name == &quot;UserID&quot; {
// 					addResolver = true
// 				}
// 			}
// 			return addResolver
// 		},
// 	},
// 	{
// 		ImportPath:        &quot;github.com/my-repo/app/backend/auth&quot;,
// 		ImportAlias:       &quot;auth&quot;,
// 		ScopeResolverName: &quot;UserOrganizationIDFromContext&quot;, // function which is called with the context of the resolver
// 		BoilerColumnName:  &quot;UserOrganizationID&quot;,
// 		AddHook: func(model *gbgen.BoilerModel, resolver *gbgen.Resolver, templateKey string) bool {
// 			// fmt.Println(model.Name)
// 			// fmt.Println(templateKey)
// 			// templateKey contains a unique where the resolver tries to add something
// 			// e.g.
// 			// most of the time you can ignore this
// 			var addResolver bool
// 			for _, field := range model.Fields {
// 				if field.Name == &quot;UserOrganizationID&quot; {
// 					addResolver = true
// 				}
// 			}
// 			return addResolver
// 		},
// 	},
// },
},
).GenerateCode(data); err != nil {
log.Fatal().Err(err).Msg(&quot;error while generating resolvers&quot;)
}
}
}

Following is log

> go run convert/convert.go
>
> 4:10PM DBG [boiler-cache] building cache
>
> 4:10PM DBG [boiler-cache] built cache!
>
> 4:10PM DBG write GraphQL schema to disk bytes=3918
> file=../schema.graphql
>
> 4:10PM DBG formatting GraphQL schema
>
> ../schema.graphql 71ms 4:10PM DBG formatted GraphQL schema
>
> 4:10PM DBG [model-cache] get structs
>
> 4:10PM DBG [model-cache] get extra's from schema
>
> 4:10PM DBG [model-cache] enhance structs with information
>
> 4:10PM DBG [model-cache] built cache!
>
> 4:10PM DBG [convert] render generated_convert.gotpl
>
> 4:10PM DBG [convert] rendered generated_convert.gotpl
>
> 4:10PM DBG [convert] render generated_convert_batch.gotpl
>
> 4:10PM DBG [convert] rendered generated_convert_batch.gotpl
>
> 4:10PM DBG [convert] render generated_convert_input.gotpl
>
> 4:10PM DBG [convert] rendered generated_convert_input.gotpl
>
> 4:10PM DBG [convert] render generated_filter.gotpl
>
> 4:10PM DBG [convert] rendered generated_filter.gotpl
>
> 4:10PM DBG [convert] render generated_preload.gotpl
>
> 4:10PM DBG [convert] rendered generated_preload.gotpl
>
> 4:10PM DBG [convert] render generated_sort.gotpl
>
> 4:10PM ERR could not parse golang file error="src.go:1:1: expected
> 'package', found 'EOF'"
>
> 4:10PM ERR error while rendering generated_sort.gotpl error="errors
> while writing template to helpers/generated_sort.go writeError: <nil>,
> contentError: execute: template: :44:17: executing &quot;&quot; at
> <$field.Enum.Name>: nil pointer evaluating *structs.Enum.Name,
> importError: helpers/generated_sort.go:1:1: expected 'package', found
> 'EOF'"
>
> 4:10PM DBG [convert] rendered generated_sort.gotpl
>
> 4:10PM ERR could not parse golang file error="src.go:1:1: expected
> 'package', found 'EOF'"
>
> 4:10PM ERR could not close file error="invalid argument"
> fileName=resolvers/all_generated_resolvers.go
>
> 4:10PM FTL error while generating resolvers error="errors while
> printing template to resolvers/all_generated_resolvers.go invalid
> argument"
>
> exit status 1

Please any help how to fix this ?

答案1

得分: 1

在convert.go中通过映射正确的目录解决了问题。

在convert.go中创建结构体时:

// output表示从gqlgen-sqlboiler生成文件的文件夹
output := structs.Config{
Directory: "helpers", // 支持根目录或子目录
PackageName: "helpers",
}

// backend是存放所有sqlboiler模型生成文件的文件夹
backend := structs.Config{
Directory: "models",
PackageName: "models",
}

// !!!重要:frontend是从gqlgen生成的所有graphql文件的文件夹
frontend := structs.Config{
Directory: "graph",
PackageName: "graph",
}

前端文件夹的映射错误。

英文:

Resolved issue by mapping correct dir. in side convert.go
in convert.go while creating structs

//output represents folder where files will be generated from gqlgen-sqlboiler

output := structs.Config{
Directory:   &quot;helpers&quot;, // supports root or sub directories
PackageName: &quot;helpers&quot;,
}

//backend is the folder where all sqlboiler models are generated

backend := structs.Config{
Directory:   &quot;models&quot;,
PackageName: &quot;models&quot;,
}

//!!!important frontend is the folder where all graphql files are generated from gqlgen

frontend := structs.Config{
Directory:   &quot;graph&quot;,
PackageName: &quot;graph&quot;,
}

front-end folder was wrongly mapped.

huangapple
  • 本文由 发表于 2023年6月20日 19:06:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76514071.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定