What is the correct way to save post data (with integer and string values) in the database golang?

huangapple go评论125阅读模式
英文:

What is the correct way to save post data (with integer and string values) in the database golang?

问题

我有以下的Go语言代码:

  1. package main
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "gopkg.in/mgo.v2"
  5. "gopkg.in/mgo.v2/bson"
  6. "log"
  7. "time"
  8. )
  9. func main() {
  10. router := gin.Default()
  11. router.POST("/save-address", SaveAddress)
  12. router.Run()
  13. }
  14. func SaveAddress(c *gin.Context) {
  15. var err error
  16. conditions := bson.M{}
  17. c.Request.ParseForm()
  18. for key, _ := range c.Request.PostForm {
  19. if key != "id" {
  20. conditions[key] = c.PostForm(key)
  21. }
  22. }
  23. conditions["_id"] = 1
  24. mongoSession := ConnectDb()
  25. sessionCopy := mongoSession.Copy()
  26. defer sessionCopy.Close()
  27. getCollection := mongoSession.DB("bformssettings").C("address")
  28. err = getCollection.Insert(conditions)
  29. if err != nil {
  30. println(err)
  31. } else {
  32. println("Data saved successfully!!!")
  33. }
  34. }
  35. func ConnectDb() (mongoSession *mgo.Session) {
  36. mongoDBDialInfo := &mgo.DialInfo{
  37. Addrs: []string{"localhost:27017"},
  38. Timeout: 60 * time.Second,
  39. Database: "bformssettings",
  40. }
  41. mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)
  42. if err != nil {
  43. log.Fatalf("CreateSession: %s\n", err)
  44. }
  45. mongoSession.SetMode(mgo.Monotonic, true)
  46. return mongoSession
  47. }

当我运行这段代码时,以下格式的数据将保存在数据库中:

  1. { "_id" : 1, "customer_id" : "3", "address" : "Chicago, IL", "city" : "Chicago", "state" : "IL", "zipcode" : "60647" }

问题:

customer_id 是一个整数值,但它将以字符串形式保存在数据库中。

可能的解决方法:

在将其保存到数据库之前,可以将 id 的字符串表示重新转换为整数。

问题:

是否有其他方法可以按原样保存数据?例如,将整数值保存为整数值?

英文:

I've the following golang code:

  1. package main
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "gopkg.in/mgo.v2"
  5. "gopkg.in/mgo.v2/bson"
  6. "log"
  7. "time"
  8. )
  9. func main() {
  10. router := gin.Default()
  11. router.POST("/save-address", SaveAddress)
  12. router.Run()
  13. }
  14. func SaveAddress(c *gin.Context){
  15. var err error
  16. conditions := bson.M{}
  17. c.Request.ParseForm()
  18. for key, _ := range c.Request.PostForm {
  19. if key != "id"{
  20. conditions[key] = c.PostForm(key)
  21. }
  22. }
  23. conditions["_id"] = 1
  24. mongoSession := ConnectDb()
  25. sessionCopy := mongoSession.Copy()
  26. defer sessionCopy.Close()
  27. getCollection := mongoSession.DB("bformssettings").C("address")
  28. err = getCollection.Insert(conditions)
  29. if err != nil{
  30. println(err)
  31. }else{
  32. println("Data saved successfully!!!")
  33. }
  34. }
  35. func ConnectDb() (mongoSession *mgo.Session) {
  36. mongoDBDialInfo := &mgo.DialInfo{
  37. Addrs: []string{"localhost:27017"},
  38. Timeout: 60 * time.Second,
  39. Database: "bformssettings",
  40. }
  41. mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)
  42. if err != nil {
  43. log.Fatalf("CreateSession: %s\n", err)
  44. }
  45. mongoSession.SetMode(mgo.Monotonic, true)
  46. return mongoSession
  47. }

When I run the code, data of the following format will be saved in the database:

  1. { "_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()来实现。

  1. for key, _ := range c.Request.PostForm {
  2. value := c.PostForm(key)
  3. if key == "customer_id" {
  4. if id, err := strconv.Atoi(value); err != nil {
  5. // 不是一个有效的数字,处理错误
  6. } else {
  7. conditions[key] = id
  8. }
  9. } else {
  10. if key != "id" {
  11. conditions[key] = value
  12. }
  13. }
  14. }

你必须以某种方式定义哪些字段应该保存整数值。我只是展示了一种处理单个字段的方法。如果你有多个字段,你可以将它们列在一个切片中,并使用单个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.

  1. for key, _ := range c.Request.PostForm {
  2. value := c.PostForm(key)
  3. if key == "customer_id" {
  4. if id, err := strconv.Atoi(value); err != nil {
  5. // Not a valid number, handle error
  6. } else {
  7. conditions[key] = id
  8. }
  9. } else {
  10. if key != "id"{
  11. conditions[key] = value
  12. }
  13. }
  14. }

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.

huangapple
  • 本文由 发表于 2017年8月15日 18:02:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/45690659.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定