英文:
What is the correct way to save post data (with integer and string values) in the database golang?
问题
我有以下的Go语言代码:
package main
import (
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
"time"
)
func main() {
router := gin.Default()
router.POST("/save-address", SaveAddress)
router.Run()
}
func SaveAddress(c *gin.Context) {
var err error
conditions := bson.M{}
c.Request.ParseForm()
for key, _ := range c.Request.PostForm {
if key != "id" {
conditions[key] = c.PostForm(key)
}
}
conditions["_id"] = 1
mongoSession := ConnectDb()
sessionCopy := mongoSession.Copy()
defer sessionCopy.Close()
getCollection := mongoSession.DB("bformssettings").C("address")
err = getCollection.Insert(conditions)
if err != nil {
println(err)
} else {
println("Data saved successfully!!!")
}
}
func ConnectDb() (mongoSession *mgo.Session) {
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{"localhost:27017"},
Timeout: 60 * time.Second,
Database: "bformssettings",
}
mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
log.Fatalf("CreateSession: %s\n", err)
}
mongoSession.SetMode(mgo.Monotonic, true)
return mongoSession
}
当我运行这段代码时,以下格式的数据将保存在数据库中:
{ "_id" : 1, "customer_id" : "3", "address" : "Chicago, IL", "city" : "Chicago", "state" : "IL", "zipcode" : "60647" }
问题:
customer_id
是一个整数值,但它将以字符串形式保存在数据库中。
可能的解决方法:
在将其保存到数据库之前,可以将 id
的字符串表示重新转换为整数。
问题:
是否有其他方法可以按原样保存数据?例如,将整数值保存为整数值?
英文:
I've the following golang code:
package main
import (
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
"time"
)
func main() {
router := gin.Default()
router.POST("/save-address", SaveAddress)
router.Run()
}
func SaveAddress(c *gin.Context){
var err error
conditions := bson.M{}
c.Request.ParseForm()
for key, _ := range c.Request.PostForm {
if key != "id"{
conditions[key] = c.PostForm(key)
}
}
conditions["_id"] = 1
mongoSession := ConnectDb()
sessionCopy := mongoSession.Copy()
defer sessionCopy.Close()
getCollection := mongoSession.DB("bformssettings").C("address")
err = getCollection.Insert(conditions)
if err != nil{
println(err)
}else{
println("Data saved successfully!!!")
}
}
func ConnectDb() (mongoSession *mgo.Session) {
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{"localhost:27017"},
Timeout: 60 * time.Second,
Database: "bformssettings",
}
mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
log.Fatalf("CreateSession: %s\n", err)
}
mongoSession.SetMode(mgo.Monotonic, true)
return mongoSession
}
When I run the code, data of the following format will be saved in the database:
{ "_id" : 1, "customer_id" : "3", "address" : "Chicago, IL", "city" : "Chicago", "state" : "IL", "zipcode" : "60647" }
Problem:
customer_id
is an integer value, but it will be saved as string in the database.
Possible workaround:
It is possible to reconvert the string representation of id
back to integer before saving it in the database.
Question:
Is there another way to save data as it is? E.g. to save integer values as integer values?
答案1
得分: 1
如果你查看保存的文档,你会发现_id
属性已经是一个数字(而不是字符串),所以是的,这是完全可能的。
customer_id
属性最终成为字符串类型的原因是,你保存的文档(conditions
变量)在customer_id
属性上保存了一个字符串值。它是字符串类型,是因为你用Context.PostForm()
的返回值填充了它,该函数将表单值作为字符串返回。
如果你希望它在数据库中是一个整数,那么在将其设置到conditions
之前,将其转换为Go整数。你可以使用strconv.Atoi()
来实现。
for key, _ := range c.Request.PostForm {
value := c.PostForm(key)
if key == "customer_id" {
if id, err := strconv.Atoi(value); err != nil {
// 不是一个有效的数字,处理错误
} else {
conditions[key] = id
}
} else {
if key != "id" {
conditions[key] = value
}
}
}
你必须以某种方式定义哪些字段应该保存整数值。我只是展示了一种处理单个字段的方法。如果你有多个字段,你可以将它们列在一个切片中,并使用单个for
循环来检测/处理所有字段;或者更好的办法是将它们放入一个充当集合的映射中,你可以在不使用for
循环的情况下检测这些字段。
另一种选择是创建一个struct
类型来建模你的表单输入数据,并使用像Gorilla的schema这样的库以类型感知的方式将其解组成该结构。
英文:
If you look at your saved document, you can see it's _id
property is already a number (and not a string), so yes, this is definitely possible.
The reason why you end up with a customer_id
property being of type string
is because the document you save (conditions
variable) holds a string
value for customer_id
property. And it is of type string
because you filled it with the return value of Context.PostForm()
which returns a form value as a string
.
If you want it to be an integer in the database, convert it to a Go integer before setting it in conditions
. For that you may use strconv.Atoi()
for example.
for key, _ := range c.Request.PostForm {
value := c.PostForm(key)
if key == "customer_id" {
if id, err := strconv.Atoi(value); err != nil {
// Not a valid number, handle error
} else {
conditions[key] = id
}
} else {
if key != "id"{
conditions[key] = value
}
}
}
You have to define somehow which fields are supposed to hold integer values. I just showed a way to do that with a single field. If you have multiple of them, you may list them in a slice, and use a single for
loop to detect / handle all; or even better, put them in a map that acts as a set, and you can detect these fields without a for
loop.
Another option would be to create a struct
type modeling your form input data, and use a library like Gorilla's schema to unmarshal into that struct in a type-aware manner.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论