英文:
go mysql returning null values
问题
我目前正在处理一个使用Golang Google App Engine的项目,并遇到了一个小问题。我有一个名为"party"的数据库,其中包含一个名为"parties"的表。问题是,当执行以下代码时,会打印一个空的JSON数组 - 实际上它的长度是正确的,但它只包含空的Parties。(而且我的数据库中确实有条目)
以下是代码的一部分:
func getParties(w http.ResponseWriter, r *http.Request) {
rows := getRowsFromSql("select * from parties;")
parties := scanForParties(rows)
json, _ := json.Marshal(parties)
fmt.Fprint(w, string(json))
}
func scanForParties(rows *sql.Rows) []Party {
var parties []Party
for rows.Next() {
var id int
var name, author, datetime, datetime_to, host, location, description, longtitude, latitude, primary_image_id string
rows.Scan(&id, &name, &author, &datetime, &datetime_to, &host, &location, &description, &longtitude, &latitude, &primary_image_id)
party := Party{
Id: id,
Name: name,
Author: author,
Datetime: datetime,
Datetime_to: datetime_to,
Host: host,
Location: location,
Description: description,
Longtitude: longtitude,
Latitude: latitude,
PrimaryImgId: primary_image_id,
}
parties = append(parties, party)
}
return parties
}
func getRowsFromSql(query string) *sql.Rows {
con, err := sql.Open("mysql", dbConnectString)
if err != nil {
panic(err)
}
defer con.Close()
rows, err2 := con.Query(query)
if err != nil {
panic(err2)
}
return rows
}
type Party struct {
Id int
Name string
Author string
Datetime string
Datetime_to string
Host string
Location string
Description string
Longtitude string
Latitude string
PrimaryImgId string
}
这是我的parties表:
mysql> describe parties;
+------------------+----------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | | | |
| author | varchar(64) | YES | | NULL | |
| datetime | datetime | YES | | NULL | |
| last_edited | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| datetime_to | datetime | YES | | NULL | |
| host | text | YES | | NULL | |
| location | text | YES | | NULL | |
| description | text | YES | | NULL | |
| longitude | decimal(23,20) | YES | | NULL | |
| latitude | decimal(23,20) | YES | | NULL | |
| primary_image_id | varchar(256) | YES | | NULL | |
+------------------+----------------+------+-----+-------------------+-----------------------------+
然而,这个旧版本的代码完全正常:
func getParties(w http.ResponseWriter, r *http.Request) {
con, dbErr := sql.Open("mysql", dbConnectString)
defer con.Close()
if dbErr == nil {
rows, _ := con.Query("select id, name, author, datetime from parties where datetime >= NOW();")
var parties []Party
var id int
var name string
var author string
var datetime string
for rows.Next() {
rows.Scan(&id, &name, &author, &datetime)
party := Party{}
party.Id = id
party.Name = name
party.Author = author
party.Datetime = datetime
parties = append(parties, party)
}
if len(parties) > 0 {
json, _ := json.Marshal(parties)
fmt.Fprint(w, string(json))
} else {
fmt.Fprint(w, "{}")
}
} else {
fmt.Fprint(w, "{\"Error\"}")
}
}
有任何想法为什么会出现这种情况吗?提前谢谢
英文:
I am currently working on a Golang Google App Engine Project and have run into a small problem. I have a database "party" with table "parties". The problem is that when the following code is executed, a EMPTY json array is printed - it actually is properly long, but it only contains empty Parties. (And I do have entries in my database)
Go code (not all of it):
func getParties(w http.ResponseWriter, r *http.Request) {
rows := getRowsFromSql("select * from parties;")
parties := scanForParties(rows)
json, _ := json.Marshal(parties)
fmt.Fprint(w, string(json))
}
func scanForParties(rows *sql.Rows) []Party {
var parties []Party
for rows.Next() {
var id int
var name, author, datetime, datetime_to, host, location, description, longtitude, latitude, primary_image_id string
rows.Scan(&id, &name, &author, &datetime, &datetime_to, &host, &location, &description, &longtitude, &latitude, &primary_image_id)
party := Party{
Id: id,
Name: name,
Author: author,
Datetime: datetime,
Datetime_to: datetime_to,
Host: host,
Location: location,
Description: description,
Longtitude: longtitude,
Latitude: latitude,
PrimaryImgId: primary_image_id,
}
parties = append(parties, party)
}
return parties
}
func getRowsFromSql(query string) *sql.Rows {
con, err := sql.Open("mysql", dbConnectString)
if err != nil {
panic(err)
}
defer con.Close()
rows, err2 := con.Query(query)
if err != nil {
panic(err2)
}
return rows
}
type Party struct {
Id int
Name string
Author string
Datetime string
Datetime_to string
Host string
Location string
Description string
Longtitude string
Latitude string
PrimaryImgId string
}
And my parties table:
mysql> describe parties;
+------------------+----------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | | | |
| author | varchar(64) | YES | | NULL | |
| datetime | datetime | YES | | NULL | |
| last_edited | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| datetime_to | datetime | YES | | NULL | |
| host | text | YES | | NULL | |
| location | text | YES | | NULL | |
| description | text | YES | | NULL | |
| longitude | decimal(23,20) | YES | | NULL | |
| latitude | decimal(23,20) | YES | | NULL | |
| primary_image_id | varchar(256) | YES | | NULL | |
+------------------+----------------+------+-----+-------------------+-----------------------------+
However, this old version of code works just fine:
func getParties(w http.ResponseWriter, r *http.Request) {
con, dbErr := sql.Open("mysql", dbConnectString)
defer con.Close()
if dbErr == nil {
rows, _ := con.Query("select id, name, author, datetime from parties where datetime >= NOW();")
var parties []Party
var id int
var name string
var author string
var datetime string
for rows.Next() {
rows.Scan(&id, &name, &author, &datetime)
party := Party{}
party.Id = id
party.Name = name
party.Author = author
party.Datetime = datetime
parties = append(parties, party)
}
if len(parties) > 0 {
json, _ := json.Marshal(parties)
fmt.Fprint(w, string(json))
} else {
fmt.Fprint(w, "{}")
}
} else {
fmt.Fprint(w, "{\"Error\"}")
}
}
Any idea why this happens?
Thanks in advance
答案1
得分: 1
这只是一个猜测,但我认为问题出在你在这里关闭了与数据库的连接:
defer con.Close()
当getRowsFromSql
返回时,这将关闭与数据库的连接,所以当你在scanForParties
中开始调用rows.Next()
时,数据库连接已经关闭了。一旦数据库连接关闭,任何行的集合都将不再可用。
可能会因此返回一个error
,但由于你没有在任何地方检查错误,所以你不会知道。在Go语言中,习惯上在函数可能返回错误时检查错误(其他语言也是如此,只是在Go语言中更加如此,因为没有异常机制)。
英文:
This is a guess, but I'm thinking that it's because you're closing the connection to the database here:
defer con.Close()
This will close the connection to the database when getRowsFromSql
returns, so by the time you start calling rows.Next()
in scanForParties
the DB connection is gone. Once the DB connection is closed, any collection of rows will no longer be available.
Something is probably returning an error
because of this, but since you're not checking any errors anywhere you won't know. In Go it is idiomatic to check for errors whenever a function can return one (and other languages too, just more so in Go because of the lack of exceptions).
答案2
得分: 1
好的,以下是翻译好的内容:
好的,其他人关于错误的说法都是正确的:rows.Scan() 返回一个错误。当我最终检查时,它说提供的扫描变量不足。简单修复:添加缺失的变量。
谢谢大家
英文:
Okay so all the others were right about the errors: rows.Scan() returns an error. And when I finally checked it, it said that there are insufficient scan variables provided. Simple fix: add the missing one.
Thank you guys
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论