首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgresql Golang Martini插入密钥

Postgresql Golang Martini插入密钥
EN

Stack Overflow用户
提问于 2015-08-01 00:38:16
回答 1查看 944关注 0票数 0

我正在使用martini、golang和postgresql构建一个社交网络类型的服务器作为练习,以帮助我在这三个方面发展技能。我遇到的几个关键问题是如何将user表中的主键插入user info表的正确行(以便将user info与特定用户连接起来)。我相信也有一种方法可以将这两个查询合并到一个更简洁的postgres脚本中……

代码语言:javascript
复制
func CreateUser(ren render.Render, r *http.Request, db *sql.DB) {

  _, err := db.Query("INSERT INTO users (first, last, email, password, karma, value) SELECT  CAST ($3 AS VARCHAR), $1, $2, $4, $5, $6 WHERE NOT EXISTS (SELECT * FROM users WHERE email = $3)",
    r.FormValue("first"),
    r.FormValue("last"),
    r.FormValue("email"),
    r.FormValue("password"),
    0,
    0)

  PanicIf(err)

  _, err = db.Query("INSERT INTO userinfo (usr, dob, phonenum, bio, mates, bought, sold) VALUES ($1, $2, $3, $4, $5, $6, $7)",
        0,
        r.FormValue("dob"),
        r.FormValue("phonenum"),
        r.FormValue("bio"),
        0,
        0,
        0)

  PanicIf(err)

  ren.Redirect("/")
}

下面是创建用户表的脚本:

代码语言:javascript
复制
DROP TABLE IF EXISTS "public"."users";
CREATE TABLE "public"."users" (
    "id" serial NOT NULL,
    "first" varchar(40) NOT NULL COLLATE "default",
    "last" varchar(40) NOT NULL COLLATE "default",
    "email" varchar(40) NOT NULL COLLATE "default",
    "password" varchar(40) NOT NULL COLLATE "default",
    "karma" int NOT NULL,
    "value" int NOT NULL
)
WITH (OIDS=FALSE);

我意识到,在生产级代码中,我不想像这样存储密码。我也被如何将非全局参数拉到数据库中而感到困惑,因为它是由m.get和m.post命令创建的。

代码语言:javascript
复制
 m.Post("/newuser", CreateUser)
 m.Get("/user", NewUser)

任何关于合并和添加来自用户的密钥到userinfo中的适当条目的建议都将非常感谢……我意识到这些可能是非常愚蠢的问题,但请原谅我的天真。

EN

回答 1

Stack Overflow用户

发布于 2015-08-01 01:22:11

为此,我从第一个查询中返回插入的用户id,并在第二个查询中使用它,但我没有使用upsert。

因此,您可以尝试使用RETURNING返回新添加的用户的id,或者通过电子邮件单独查询它(因为在本例中,电子邮件对于每个用户都是唯一的)。

然后使用它进行第二次查询:

代码语言:javascript
复制
_, err = db.Query(`INSERT INTO userinfo (usr, dob, phonenum, bio, mates, bought, sold)
                   VALUES ($1, $2, $3, $4, $5, $6, $7)`,
    id, // there
    r.FormValue("dob"),
    r.FormValue("phonenum"),
    ...

我假设usr是用户id (users.id的外键)

示例源代码:

代码语言:javascript
复制
package main

import (
    "database/sql"
    "fmt"
    _ "github.com/lib/pq"
    "log"
)

func main() {
    db, err := sql.Open("postgres", "user=alex dbname=tmp sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }

    rows, err := db.Query(`
        INSERT INTO users (first, last, email, password, karma, value)
        SELECT  CAST ($3 AS VARCHAR), $1, $2, $4, $5, $6
        WHERE NOT EXISTS (SELECT * FROM users WHERE email = $3)
        RETURNING id`,
        "first", "last", "email", "password", 0, 0)
    defer rows.Close()
    if err != nil {
        log.Fatal(err)
    }

    if rows.Next() {
        id := 0
        rows.Scan(&id)
        _, err = db.Exec(`INSERT INTO userinfo (user_id, info) VALUES ($1, $2)`, id, "info")
        if err != nil {
            log.Fatal(err)
        }

        fmt.Println("Inserted:", id)
    }

}

我个人更喜欢QueryRow而不是query,因为它更明显地返回一行,但它也可以与Query一起工作。

此外,我还建议对电子邮件使用唯一索引,而不是子查询。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31751111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档