Golang PGX:扫描行时带有返回语句的更新返回错误
我将Postgres与PostGis扩展名一起使用, pgx & sqlf 插入/删除和读取行的工作正常,我只是在努力争夺一行的更新,因为当我尝试将返回的行扫描到GO结构中时,我总是会从pgx
中返回此错误。
no rows in result set
以下是我创建的用于进行部分更新的方法。我首先创建SQL查询并设置列以更新,还添加返回
语句以返回整个行。由于我的位置列是一个后点,我需要用st_asbinary
函数包装列,以便我可以将其扫描到 orb.point 。
type UpdatePartyParams struct {
ID string
Title string
Lat float32
Long float32
StreetAddress string
PostalCode string
State string
Country string
StartDate time.Time
EndDate time.Time
}
func (d Directory) UpdateParty(ctx context.Context, arg UpdatePartyParams) (Party, error) {
sqlf.SetDialect(sqlf.PostgreSQL)
b := sqlf.Update(TABLE_NAME)
if arg.Title != "" {
b = b.Set("title", arg.Title)
}
if arg.Lat != 0 && arg.Long != 0 {
b = b.SetExpr("location", "ST_SetSRID(ST_MakePoint(?, ?), 4326)", arg.Long, arg.Lat)
}
if arg.StreetAddress != "" {
b = b.Set("street_address", arg.StreetAddress)
}
if arg.PostalCode != "" {
b = b.Set("postal_code", arg.PostalCode)
}
if arg.State != "" {
b = b.Set("state", arg.State)
}
if arg.Country != "" {
b = b.Set("country", arg.Country)
}
startYear := arg.StartDate.Year()
if !(startYear == 1970) {
b = b.Set("start_date", arg.StartDate)
}
endYear := arg.StartDate.Year()
if !(endYear == 1970) {
b = b.Set("end_date", arg.EndDate)
}
b.
Where("id = ?", arg.ID).
Returning("id, user_id, title, is_public, ST_AsBinary(location) AS location, street_address, postal_code, state, country, start_date, end_date")
log.Println(b.String()) // UPDATE parties SET title=$1 WHERE id = $2 RETURNING id, user_id, title, is_public, ST_AsBinary(location) AS location, street_address, postal_code, state, country, start_date, end_date
row := d.pool.QueryRow(ctx, b.String(), b.Args()...)
var i Party
err := row.Scan(
&i.ID,
&i.UserID,
&i.Title,
&i.IsPublic,
wkb.Scanner(&i.Location),
&i.StreetAddress,
&i.PostalCode,
&i.State,
&i.Country,
&i.StartDate,
&i.EndDate,
)
return i, err
}
我的数据库架构
CREATE TABLE parties (
id varchar(27) PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT NOT NULL,
is_public BOOLEAN NOT NULL DEFAULT false,
location geometry(POINT, 4326) NOT NULL,
street_address TEXT,
postal_code TEXT,
state TEXT,
country TEXT,
start_date TIMESTAMP,
end_date TIMESTAMP
);
上述错误是由 row.scan 方法并抛出“如果找不到行” 。但是,当我使用差异SQL UI客户端执行SQL语句时,它可以正常运行,并且返回了行。知道什么可能导致row.scan()
方法失败,而行不返回?
编辑
怪异的部分是,一行的简单读取效果很好,并将返回的记录扫描到GO结构中。以下是一种工作方法,它仅通过select
语句使用相同的row.scan
方法。
func (d PartyRepository) GetParty(ctx context.Context, id string) (Party, error) {
sqlf.SetDialect(sqlf.PostgreSQL)
b := sqlf.
Select("id, user_id, title, is_public, ST_AsBinary(location) AS location, street_address, postal_code, state, country, start_date, end_date").
From(TABLE_NAME).
Where("id = ?", id)
log.Println(b.String())
row := d.pool.QueryRow(ctx, b.String(), b.Args()...)
var i Party
err := row.Scan(
&i.ID,
&i.UserID,
&i.Title,
&i.IsPublic,
wkb.Scanner(&i.Location),
&i.StreetAddress,
&i.PostalCode,
&i.State,
&i.Country,
&i.StartDate,
&i.EndDate,
)
return i, err
}
I use Postgres with the Postgis extension and pgx & sqlf on the Go side.
Inserting/deleting and reading Rows works fine I'm just struggeling with Updates of a row since I always get this error returned from pgx
when I try to scan the returned row into a Go struct.
no rows in result set
Below is the method I created to do partial updates. I first creates the SQL query and set columns to update and also add a RETURNING
statement to return the whole row. Since my location column is a Postgis Point I need to wrap the column with the ST_AsBinary
function so that I can scan it into an Orb.Point.
type UpdatePartyParams struct {
ID string
Title string
Lat float32
Long float32
StreetAddress string
PostalCode string
State string
Country string
StartDate time.Time
EndDate time.Time
}
func (d Directory) UpdateParty(ctx context.Context, arg UpdatePartyParams) (Party, error) {
sqlf.SetDialect(sqlf.PostgreSQL)
b := sqlf.Update(TABLE_NAME)
if arg.Title != "" {
b = b.Set("title", arg.Title)
}
if arg.Lat != 0 && arg.Long != 0 {
b = b.SetExpr("location", "ST_SetSRID(ST_MakePoint(?, ?), 4326)", arg.Long, arg.Lat)
}
if arg.StreetAddress != "" {
b = b.Set("street_address", arg.StreetAddress)
}
if arg.PostalCode != "" {
b = b.Set("postal_code", arg.PostalCode)
}
if arg.State != "" {
b = b.Set("state", arg.State)
}
if arg.Country != "" {
b = b.Set("country", arg.Country)
}
startYear := arg.StartDate.Year()
if !(startYear == 1970) {
b = b.Set("start_date", arg.StartDate)
}
endYear := arg.StartDate.Year()
if !(endYear == 1970) {
b = b.Set("end_date", arg.EndDate)
}
b.
Where("id = ?", arg.ID).
Returning("id, user_id, title, is_public, ST_AsBinary(location) AS location, street_address, postal_code, state, country, start_date, end_date")
log.Println(b.String()) // UPDATE parties SET title=$1 WHERE id = $2 RETURNING id, user_id, title, is_public, ST_AsBinary(location) AS location, street_address, postal_code, state, country, start_date, end_date
row := d.pool.QueryRow(ctx, b.String(), b.Args()...)
var i Party
err := row.Scan(
&i.ID,
&i.UserID,
&i.Title,
&i.IsPublic,
wkb.Scanner(&i.Location),
&i.StreetAddress,
&i.PostalCode,
&i.State,
&i.Country,
&i.StartDate,
&i.EndDate,
)
return i, err
}
My Database Schema
CREATE TABLE parties (
id varchar(27) PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT NOT NULL,
is_public BOOLEAN NOT NULL DEFAULT false,
location geometry(POINT, 4326) NOT NULL,
street_address TEXT,
postal_code TEXT,
state TEXT,
country TEXT,
start_date TIMESTAMP,
end_date TIMESTAMP
);
The mentioned error is caused by the row.Scan method and thrown "If no rows were found". But when I execute the sql statement with a difference SQL UI client it works fine and the row is returned. Any Idea what could cause the row.Scan()
method to fail and the row not to be returned?
Edit
The weird part is that a simple read for one row works fine and scans the returned record into the Go struct. Below is a working method which uses the same row.Scan
method just through a select
statement.
func (d PartyRepository) GetParty(ctx context.Context, id string) (Party, error) {
sqlf.SetDialect(sqlf.PostgreSQL)
b := sqlf.
Select("id, user_id, title, is_public, ST_AsBinary(location) AS location, street_address, postal_code, state, country, start_date, end_date").
From(TABLE_NAME).
Where("id = ?", id)
log.Println(b.String())
row := d.pool.QueryRow(ctx, b.String(), b.Args()...)
var i Party
err := row.Scan(
&i.ID,
&i.UserID,
&i.Title,
&i.IsPublic,
wkb.Scanner(&i.Location),
&i.StreetAddress,
&i.PostalCode,
&i.State,
&i.Country,
&i.StartDate,
&i.EndDate,
)
return i, err
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论