sqlc icon indicating copy to clipboard operation
sqlc copied to clipboard

Exclude columns from `sqlc.embed`

Open Couper4 opened this issue 1 month ago • 2 comments

Is there a way to exclude columns from sqlc.embed(my_table)?

It would be useful to avoid reading from specific columns (e.g. columns you need to drop, and you want to stop reading before actually dropping them), without loosing the nice generated struct.

Couper4 avatar Nov 07 '25 12:11 Couper4

I don't know your usecase, but embed will always only create a query that has all of the rows on that particular table in your schema. So as long as you have ran sqlc generate and have that code run after the migration - you should have nothing to worry about. The advantage of embed is that since it selects all columns from a table, it can reuse the model struct for that table and you don't have to do any sort of marshalling. If it didn't read some columns, you would have to implicitly know at the application layer that some of the fields of the struct are always zero values because they were never read.

gamebox avatar Nov 21 '25 02:11 gamebox

I could also benefit from this feature. Version 1 of my service is running and has some columns that I wish to drop. My queries are configured to use embeds for my structs. I would like to do a blue/green deploy of version 2 of my service. If I run migrations prior to deploying version 2, my version 1 code will currently break as it will attempt to read columns that no longer exist.

With the ability to exclude some columns from a "star" query or embed, I can add excludes to version 2 of my service and safely remove references to the columns-to-be-dropped. In version 3 remove the excludes and remove the columns.

-- migration_1.sql
CREATE TABLE foo (bar int, baz text);

-- queries_1.sql
SELECT sqlc.embed(foo) FROM foo;

With expected generated Go:

type Foo struct {
    Bar int
    Baz string
}

query := "SELECT foo.bar, foo.baz FROM foo;"

Then to safely remove references to foo.baz

-- queries_2.sql
SELECT sqlc.embed(foo), sqlc.exclude(foo.baz) FROM foo;

Which would then generate something akin to the following:

type Foo struct {
    Bar int
}

query := "SELECT foo.bar FROM foo;"
-- migration_3.sql
ALTER TABLE foo DROP COLUMN baz;

-- queries_3.sql
SELECT sqlc.embed(foo) FROM foo;

Which would generate the same Go code as version 2.

abborg avatar Nov 27 '25 23:11 abborg