-
Notifications
You must be signed in to change notification settings - Fork 923
Question: how to properly use UpdateFooParams and Foo class? #691
-
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?
Beta Was this translation helpful? Give feedback.
All reactions
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
-
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.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
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?
Beta Was this translation helpful? Give feedback.
All reactions
-
Correct. The goals is to add migration support further down the line, but it's not there yet
Beta Was this translation helpful? Give feedback.
All reactions
-
😄 1