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

Question: how to properly use UpdateFooParams and Foo class? #691

Discussion options

Hey,

I just started onboarding with this library, and feel like I'm trying to coerce an antipattern with the Queries.UpdateFoo(ctx, params). The params object and my model object are identical, but I can't cast them.

Here's what I have so far:

-- name: UpdateUsers :exec
UPDATE users
SET
 name = $2,
WHERE id = $1;

This generates a user.sql.go model, as expected:

type User struct {
	ID int32 `json:"id"`
	Name string `json:"name"`
}

As well as the expected:

type UpdateUsersParams struct {
	ID int32 `json:"id"`
	Name string `json:"name"`
}
func (q *Queries) UpdateUsers(ctx context.Context, arg UpdateUsersParams) error {
	_, err := q.exec(ctx, q.updateUsersStmt, updateUsers,
		arg.ID,
		arg.Name,
	)
	return err
}

The problem here is that I can't pass the User type to the UpdateUsers function, since that expects a UpdateUsersParams. As a result, I end up with code like this:

user := &db.User{Name: "user1"}
err := q.UpdateUsers(context.Background(), db.UpdateUsersParams{
	Name: user.Name,
})

This seems wrong. What am I missing?

You must be logged in to vote

By design, sqlc will never re-use parameter structs for methods, even if those structs have the same fields as other parameter or model structs. Since database schema and queries change often, this design limits the impact of those changes.

Taking your example one step further, imagine that we need to add a created_at column to the users table. This column defaults to now().

CREATE TABLE users (
 id serial primary key,
 name not null,
 created_at timestamp default now()
);
type User struct {
	ID int32 `json:"id"`
	Name string `json:"name"`
	CreatedAt time.Time `json:"created_at"`
}

Since the column can be null, we don't have to updat...

Replies: 3 comments

Comment options

By design, sqlc will never re-use parameter structs for methods, even if those structs have the same fields as other parameter or model structs. Since database schema and queries change often, this design limits the impact of those changes.

Taking your example one step further, imagine that we need to add a created_at column to the users table. This column defaults to now().

CREATE TABLE users (
 id serial primary key,
 name not null,
 created_at timestamp default now()
);
type User struct {
	ID int32 `json:"id"`
	Name string `json:"name"`
	CreatedAt time.Time `json:"created_at"`
}

Since the column can be null, we don't have to update the UpdateUsers query. If the query took in a User struct, callers may think that the CreatedAt field would be passed as a parameter when that's not the case.

You must be logged in to vote
0 replies
Answer selected by issmirnov
Comment options

understood, thank you!

Quick side question: Despite passing the CREATE TABLE calls to the generator, the sqlc boilerplate does not do any sort of database initiation, right? So I am responsible for my own table init + migrations?

You must be logged in to vote
0 replies
Comment options

Correct. The goals is to add migration support further down the line, but it's not there yet

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Converted from issue

This discussion was converted from issue #691 on August 28, 2020 16:06.

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