我有一个Postgresql jsonb列,我想在我的应用程序中检索。我能够从jsonb列中检索一个普通的旧结构/指针,但无法检索结构/指针的切片。我有:
package main
import (
"database/sql"
"encoding/json"
"fmt"
"os"
_ "github.com/lib/pq"
)
// Person is an employee
type Person struct {
Name string
Children []*Child
Job
}
// Child is a child of an employee
type Child struct {
Name string
// other fields
}
// Job is the employment of a person
type Job struct {
Position string
// other fields
}
func main() {
db, err := sql.Open("postgres",
fmt.Sprintf(
"user=%s password=%s host=%s database=%s sslmode=require",
os.Getenv("user"), os.Getenv("pword"), os.Getenv("h"), os.Getenv("db"),
),
)
if err != nil {
panic(err)
}
defer db.Close()
db.SetMaxIdleConns(0)
// create table
if _, err = db.Exec("DROP table mytable"); err != nil {
fmt.Printf("cannot delete table %v", err)
}
if _, err = db.Exec("CREATE TABLE mytable (name text, children jsonb, job jsonb)"); err != nil {
fmt.Printf("cannot create table %v", err)
}
// insert some rows
for _, person := range []Person{
Person{"Bob", []*Child{&Child{"Fred"}, &Child{"Mary"}}, Job{"welder"}},
Person{"Jane", []*Child{&Child{"Ben"}, &Child{"Emily"}}, Job{"machinist"}},
} {
c, e := json.Marshal(person.Children)
if e != nil {
fmt.Printf("cannot marshal children %v", err)
}
j, e := json.Marshal(person.Job)
if e != nil {
fmt.Printf("cannot marshal job %v", err)
}
if _, err = db.Exec("INSERT INTO mytable (name, children, job) VALUES ($1,$2,$3)", person.Name, string(c), string(j)); err != nil {
fmt.Printf("cannot insert value %v", err)
}
}
//selectJob(db)
selectChildrenAndJob(db)
}
func selectJob(db *sql.DB) {
p := &Person{}
err := db.QueryRow("SELECT job FROM mytable LIMIT 1").Scan(&p.Job)
switch {
case err == sql.ErrNoRows:
fmt.Println("No rows.")
case err != nil:
fmt.Println("cannot retrieve rows", err)
default:
fmt.Printf("job %v\n", p.Job)
}
}
func selectChildrenAndJob(db *sql.DB) {
p := &Person{}
err := db.QueryRow("SELECT children, job FROM mytable LIMIT 1").Scan(&p.Children, &p.Job)
switch {
case err == sql.ErrNoRows:
fmt.Println("No rows.")
case err != nil:
fmt.Println("cannot retrieve rows", err)
default:
fmt.Printf("children %v; job %v\n", p.Children, p.Job)
}
}
// Scan scans for Child
func (c *Child) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), c)
}
// Scan scans for Job
func (j *Job) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), j)
}
我得到的错误:
Scan error on column index 0: unsupported Scan, storing driver.Value type []uint8 into type *[]*main.Child
如果我取消注释“ selectJob(db)”并运行它就可以了。因此,我无法弄清楚如何扫描到结构/指针的一部分。有什么建议?
您跳过了JSON解码步骤。
您将以字符串形式从postgres获取jsonb字段。然后,您必须将json.Unmarshal
其放入&p.Children
:
func selectChildrenAndJob(db *sql.DB) {
p := &Person{}
var children string
err := db.QueryRow("SELECT children, job FROM mytable LIMIT 1").Scan(&children, &p.Job)
switch {
case err == sql.ErrNoRows:
fmt.Println("No rows.")
case err != nil:
fmt.Println("cannot retrieve child + job rows", err)
default:
err = json.Unmarshal([]byte(children), &p.Children)
if err != nil {
fmt.Printf("Failed to unmarshal children: %s\n", err)
return
}
childlist := make([]Child, 0)
for _, c := range p.Children {
childlist = append(childlist, *c)
}
fmt.Printf("children %v; job %v\n", childlist, p.Job)
}
}
如果其他字段不是字符串类型,您也会在其他字段上注意到这一点。
您可以认为它与您插入数据时所采取的步骤相反:
c, e := json.Marshal(person.Children)
... "VALUES ($1,$2,$3)", person.Name, string(c), // ...
childlist
和最后的相应循环只是为了满足您的打印格式并打印值而不是指针。如果您不介意打印指针,另一种选择是跳过该指针
fmt.Printf("Person with children and job: %v\n", p)
问题内容: 我不理解以下代码的行为。在创建作为结构指针切片的匹配结构列表时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12。但是,如果将匹配项更改为[]窗口小部件代替[] * Widget,然后将输出10和11。 为什么是这样? 问题答案: 那是因为当您使用指针时,您将添加到数组。 请注意,实际上这是循环中使用的局部变量,因此,这不是您要添加到数组中的地址。 (即使变
我正在执行对DynamoDB表的扫描,然后我需要将返回项中的相应属性添加到类型的列表中(具有单个构造函数)。代码当前成功扫描DB并返回扫描结果的。然而,由于某种原因,我的迭代似乎返回null。
问题内容: 我知道如何获取Android Wifi扫描,但我不知道从中制作列表适配器的最佳方法。我只想将SSID和BSSID从扫描的绑定到text1和text2。 我一直在做的样本 和: 问题答案: 试试这个代码 对于 在中添加这些权限
问题内容: 我想有一个通用的方法,无论它是作为指针,切片还是数组提供的,都将始终返回结构值。 我对此的处理方式如下: 去游乐场 如您所见,问题出在从a 或。中获取结构。 我如何扩展上面的函数以从数组或切片中获取struct的值? 更新:我要做的就是将变成。 问题答案: 如果你只是想要的类型,即使片是零,你可以使用像这样: 关于,来自http://golang.org/pkg/reflect/#Ty
我正在学习链表,以及如何在C中使用结构和指针创建链表。下面我举一个例子。据我所知,被调用的将头节点所在的结构的开始内存位置作为参数传递。push()函数的参数将结构节点作为指向指针的指针,因此它作为引用传递,而不是实际副本。因此,我们的的第一个指针只是指向头部节点的内存位置的指针,第二个指针指向该值,该值是头部节点指向的下一个内存位置。我们通过为结构节点分配一些内存,在结构节点内创建一个名为new
基本上,我试图询问用户的输入,并且输入应该使用单个扫描仪存储在两个数组中。使用two会询问用户两次,这是不切实际的。代码如下所示 如果用户选择选项1,用户将得到数组中的一些主题(我没有包括),并要求输入分数。然后输入将进入期中或期末数组,但我似乎无法使用一台扫描仪。 如果有比我提出的想法更好的想法,那么请分享。我在Java还是新手,也是第一次使用stackoverflow。谢谢!