Golang如何在SqlC中使用Validator?

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

Golang how to use Validator with SqlC

问题

有没有办法在不创建两个不同的结构体的情况下,将JSON验证[github.com/go-playground/validator/v10]和JSON查询[sqlc]结合起来?

我有以下表定义

  1. CREATE TABLE table1 (
  2. columnName1 VARCHAR(200) NOT NULL PRIMARY KEY,
  3. columnName2 VARCHAR(200) NOT NULL
  4. )

和以下查询

  1. -- name: GetTable1:one
  2. SELECT * FROM table1
  3. WHERE columnName1 = $1 LIMIT 1;

执行SQLC后,会生成以下代码

  1. ...
  2. //
  3. // This struct is created automatically by sqlC
  4. //
  5. type CreateTable1Params struct {
  6. Columnname1 string `json:"columnname1"`
  7. Columnname2 string `json:"columnname2"`
  8. }
  9. func (q *Queries) CreateTable1(ctx context.Context, arg CreateTable1Params ) (Table1, error) {
  10. ...
  11. }

现在,我需要验证CreateTable1的REST参数,假设columnName2是必需的,所以我有一个类似下面的控制器包

table1Controller.go

  1. import (
  2. ...
  3. validator "github.com/go-playground/validator/v10"
  4. )
  5. type Table1Controller struct {
  6. Validate *validator.Validate
  7. }
  8. //
  9. // This struct is created manually for validation
  10. //
  11. type InT1Param struct {
  12. ColumnName1 string `validate:"required" form:"columnName1" json:"columnName1" db:"columnname1"`
  13. ColumnName2 string `validate:"required" form:"columnName2" json:"columnName2" db:"columnname2" binding:"required"`
  14. }
  15. func (c *Table1Controller) validateInput(t1 InT1Param) error {
  16. err := service.Validate.Struct(t1)
  17. if err != nil {
  18. errStr := ""
  19. for _, mapErr := range err.(validator.ValidationErrors) {
  20. errStr = fmt.Sprintf("%s%s\n", errStr, mapErr.Translate(service.Translator))
  21. }
  22. return errors.New(errStr)
  23. }
  24. return nil
  25. }
  26. func (c *Table1Controller) Insert(ctx *gin.Context, dbQueries *dbModel.Queries, t1 InT1Param) error {
  27. err := c.validateInput(t1)
  28. if err != nil {
  29. return err
  30. inParam = dbModel.CreateTable1Param {
  31. Columnname1: t1.columnName1,
  32. Columnname2: t2.ColumnName2
  33. }
  34. outParam, err := dbQueries.CreateTable1(ctx, inParam)
  35. if err != nil {
  36. return err
  37. return nil
  38. }
英文:

Is there any way to combine the JSON validation [github.com/go-playground/validator/v10] and the JSON Query [sqlc] without having to create two different structs?

I have the following table definition

  1. CREATE TABLE table1 (
  2. columnName1 VARCHAR(200) NOT NULL PRIMARY KEY,
  3. columnName2 VARCHAR(200) NOT NULL
  4. )

And the following query

  1. -- name: GetTable1:one
  2. SELECT * FROM table1
  3. WHERE columnName1 = $1 LIMIT 1;

Executing SQLC the following code is generated

  1. ...
  2. //
  3. // This struct is created automatically by sqlC
  4. //
  5. type CreateTable1Params struct {
  6. Columnname1 string `json:"columnname1"`
  7. Columnname2 string `json:"columnname2"`
  8. }
  9. func (q *Queries) CreateTable1(ctx context.Context, arg CreateTable1Params ) (Table1, error) {
  10. ...
  11. }

Now, I need to validate the REST parameters for CreateTable1, let's say that columnName2 is required, so I have a controller package like the following

table1Controller.go

  1. import (
  2. ...
  3. validator "github.com/go-playground/validator/v10"
  4. )
  5. type Table1Controller struct {
  6. Validate *validator.Validate
  7. }
  8. //
  9. // This struct is created manually for validation
  10. //
  11. type InT1Param struct {
  12. ColumnName1 string `validate:"required" form:"columnName1" json:"columnName1" db:"columnname1"`
  13. ColumnName2 string `validate:"required" form:"columnName2" json:"columnName2" db:"columnname2" binding="required"`
  14. }
  15. func (c *Table1Controller) validateInput(t1 InT1Param) error {
  16. err := service.Validate.Struct(t1)
  17. if err != nil {
  18. errStr := ""
  19. for _, mapErr := range err.(validator.ValidationErrors) {
  20. errStr = fmt.Sprintf("%s%s\n", errStr, mapErr.Translate(service.Translator))
  21. }
  22. return errors.New(errStr)
  23. }
  24. return nil
  25. }
  26. func (c *Table1Controller) Insert(ctx *gin.Context, dbQueries *dbModel.Queries, t1 InT1Param) error {
  27. err := c.validateInput(t1)
  28. if err != nil {
  29. return err
  30. inParam = dbModel.CreateTable1Param {
  31. Columnname1: t1.columnName1,
  32. Columnname2: t2.ColumnName2
  33. }
  34. outParam, err := dbQueries.CreateTable1(ctx, inParam)
  35. if err != nil {
  36. return err
  37. return nil
  38. }

答案1

得分: 1

使用 sqlc.yaml 配置文件中的 overrides 键,我能够为列添加以下字段。

  1. version: 2
  2. sql:
  3. - schema: "./dbModel/migration/schema_20221008.sql"
  4. queries: "./dbModel/query/query.sql"
  5. engine: "postgresql"
  6. gen:
  7. go:
  8. package: "dbModel"
  9. out: "dbModel"
  10. emit_json_tags: true
  11. emit_db_tags: true
  12. emit_prepared_queries: false
  13. emit_interface: false
  14. emit_exact_table_names: false
  15. json_tags_case_style: camel
  16. overrides:
  17. - column: table1.column_name1
  18. go_struct_tag: validate:"required" x:"y,z"
  19. - column: table1.column_name2
  20. go_struct_tag: validate:"required"

这个配置为表生成了以下结构体:

  1. type table1 struct {
  2. ColumnName1 string `db:"column_name1" json:"columnName1" validate:"required" x:"y,z"`
  3. ColumnName2 string `db:"column_name2" json:"columnName2" validate:"required"`
  4. }

我无法更改 Param 结构体,但我猜想使用主结构体可以使用验证。

英文:

Using the overrides key of the sqlc.yaml configuration I was able to add the following fields to the columns.

  1. version: 2
  2. sql:
  3. - schema: "./dbModel/migration/schema_20221008.sql"
  4. queries: "./dbModel/query/query.sql"
  5. engine: "postgresql"
  6. gen:
  7. go:
  8. package: "dbModel"
  9. out: "dbModel"
  10. emit_json_tags: true
  11. emit_db_tags: true
  12. emit_prepared_queries: false
  13. emit_interface: false
  14. emit_exact_table_names: false
  15. json_tags_case_style: camel
  16. overrides:
  17. - column: table1.column_name1
  18. go_struct_tag: validate:"required" x:"y,z"
  19. - column: table1.column_name2
  20. go_struct_tag: validate:"required"

This configuration generated the following struct for the table:

  1. type table1 struct {
  2. ColumnName1 string `db:"column_name1" json:"columnName1" validate:"required" x:"y,z"`
  3. ColumnName2 string `db:"column_name2" json:"columnName2" validate:"required"`

I wasn't able to change the Param structs but I guess using the table main struct use the validation.

huangapple
  • 本文由 发表于 2022年10月13日 10:50:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/74049973.html
匿名

发表评论

匿名网友

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

确定