Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Working with pgtypes #2910

Unanswered
carlosmaranje asked this question in Q&A
Oct 25, 2023 · 4 comments · 2 replies
Discussion options

When using pgx/v5 the INSERT clause for the following schema:

CREATE TABLE "items"
(
 "id" serial PRIMARY KEY,
 "uuid" uuid NOT NULL,
 "weight" decimal,
 "name" text NOT NULL,
 "description" text,
 "created_at" timestamp DEFAULT now(),
 "deleted_at" timestamp
);

Will generate this output:

type CreateItemParams struct {
	Uuid uuid.UUID `json:"uuid"`
	Weight pgtype.Numeric `json:"weight"`
	Name string `json:"name"`
	Description pgtype.Text `json:"description"`
	CreatedAt pgtype.Timestamp `json:"created_at"`
	DeletedAt pgtype.Timestamp `json:"deleted_at"`
}
func (q *Queries) CreateItem(ctx context.Context, arg CreateItemParams) (Item, error) {
...
...
}

I am having a very hard time trying to use the CreateItem() method using pgtypes. I have found online that for text columns I can do:

description := pgtype.Text{
		String: "Test string",
		Valid: true,
	}

However, for pgtype.Numeric it is more complicated since, for example, to represent 4.53 it seems like I have to do:

 weight := pgtype.Numeric{
		Int: big.NewInt(453),
		Exp: -2,
		Status: pgtype.Present,
	}

(追記) I do not want to use overrides (追記ここまで) in the sqlc configuration, since pgtypes are intented to offer better results than Go's built-in types. However using pgtype 'as-is' I think it would require to create some methods to convert Go types to pgtypes.

My question is: Am I missing something here? Is this the way it is supposed to work? How do you usually work with these types? Any real-use example would be ideal.

You must be logged in to vote

Replies: 4 comments 2 replies

Comment options

Same issue with pgtype.Numeric generated by SQLC. I found the structure difficult to manipulate when trying to insert a float.

The only way I found is the way you mention, as changing type in DDL (like going from Numeric type to Float8) does not change the generated type (pgtype.Numeric):

pgtype.Numeric{
		Int: big.NewInt(453),
		Exp: -2,
		Status: pgtype.Present,
}
You must be logged in to vote
0 replies
Comment options

Same thing here, is there anyone that can point us in the right direction?

You must be logged in to vote
0 replies
Comment options

Here's a working solution for creating pgtype.Numeric (or other types):

	package main
	import (
		"fmt"
		"github.com/jackc/pgx/v5/pgtype"
	)
	func main() {
		f := 5.527
		num := &pgtype.Numeric{}
		err := num.Scan(fmt.Sprintf("%.2f", f)) // .2 specifies precision
		if err != nil {
			panic(err)
		}
		fmt.Printf("%+v\n", num)
	}

Result:

&{Int:+553 Exp:-2 NaN:false InfinityModifier:finite Valid:true}

Inspired by this answer on StackOverflow.

You must be logged in to vote
1 reply
Comment options

Yeah I also cross-posted this on SO and that was the answer I got. We ended up doing something like that. I'll leave it here too, in case it can help someone.

func Numeric(number float64) (value pgtype.Numeric) {
	parse := strconv.FormatFloat(number, 'f', -1, 64)
	if err := value.Scan(parse); err != nil {
		log.Fatal().Err(err).Msg("Error scanning numeric")
	}
	return value
}
func NumericNull() pgtype.Numeric {
	return pgtype.Numeric{
		Int: nil,
		Exp: 0,
		NaN: false,
		InfinityModifier: 0,
		Valid: false,
	}
}

We just use those methods everywhere.

Note that we are being verbose on purpose. You can always use the first method and take valid as a param.

Comment options

How to convert pgtype.Numeric to base 10 string? pgtype v4 has a method AssignTo can do this, but this method is missing in v5.

You must be logged in to vote
1 reply
Comment options

How about:

// num is of type pgtype.Numeric
val, err := num.Value()
if err != nil {
	panic(err)
}
s := val.(string)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /