This question already has answers here:
How do I insert multiple values into a postgres table at once?
(6 answers)
How to insert multiple data at once
(8 answers)
Closed 3 years ago.
In PostgreSQL I have a pretty simple table where I store information about relationships between users and games. Here is a working function which I use to insert data. As you can see it makes multiple SQL queries to the database which is not elegant I think. What do I need to change to insert multiple rows with one query?
var CreateRelationship = func(responseWriter http.ResponseWriter, request *http.Request) {
userID := mux.Vars(request)["user_id"]
type RequestBody struct {
Games []int `json:"games"`
}
requestBody := RequestBody{}
decoder := json.NewDecoder(request.Body)
if err := decoder.Decode(&requestBody); err != nil {
utils.ResponseWithError(responseWriter, http.StatusBadRequest, err.Error())
return
}
for i := 0; i < len(requestBody.Games); i++ {
if _, err := database.DBSQL.Exec("INSERT INTO users_games_relationship (user_id, game_id) VALUES ($1, $2);", userID, requestBody.Games[i]); err != nil {
utils.ResponseWithError(responseWriter, http.StatusInternalServerError, err.Error())
return
}
}
utils.ResponseWithSuccess(responseWriter, http.StatusOK, "All new records successfully created.")
}
Related
This question already has answers here:
How would I update multiple records based on different key in Mongo in one query?
(1 answer)
MongoDB update array of documents and replace by an array of replacement documents
(1 answer)
Closed last month.
I am trying to update a collection of multiple data in MongoDB using Golang at the same time, instead, it updates only one record, I'm using a for loop to perform this action
My filter code
if len(list_phone) > 1 {
for i := 0; i < len(list_phone); i++ {
update_userPhone, err := helpers.UpdatePhone(list_phone[i]["phone"].(string), list_phone[i]["email"].(string))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(`{"status:":"error", "error": true, "msg": "Something went wrong" }`))
return
}
json.NewEncoder(w).Encode(update_userPhone)
return
}
}
my update function
func UpdatePhone(phone string, email string) (bool, error) {
userCollection, _ := GetDBCollection("users")
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
id := email
filter := bson.M{"email": id}
update := bson.M{"$set": bson.M{"phone": phone}}
_, err := userCollection.UpdateOne(ctx, filter, update)
defer cancel()
if err != nil {
return false, err
}
return true, err
}
I'am trying to create registration in my Telegram Bot with Golang and Postgres. When user writes "register", bot has to check if user's uuid already exists in DB, and if not to create row with his uuid.
Here is my function to check if uuid already exists in DB:
func IsUserInDB(uuid int64) (bool, error) {
var exists bool
query := fmt.Sprintf("SELECT EXISTS(SELECT 1 FROM users WHERE uuid = %d);", uuid)
err := Db.QueryRow(query).Scan(&exists)
return exists, err
}
Here is my function for adding user's uuid to DB:
func AddUserToDB(column string, row interface{}) error {
query := fmt.Sprintf("INSERT INTO users (%s) VALUES (%v);", column, row)
_, err := Db.Exec(query)
return err
}
And the logic for bot:
func (b *Bot) handleMessages(message *tgbotapi.Message) error {
switch message.Text {
case "register":
exists, err := data.IsUserInDB(message.From.ID)
if err != nil {
return err
}
if !exists {
err := data.AddUserToDB("uuid", message.From.ID)
return err
}
return nil
default:
msg := tgbotapi.NewMessage(message.Chat.ID, "unknown message...")
_, err := b.bot.Send(msg)
return err
}
}
First time, when I send "register", bot successfully adds user's id to db, but the problem happens if I try to send "register" 1 more time. IsUserInDB() returns me false and bot adds 1 more row with the same uuid. So, I think problem is with my IsUserInDb() function
Why not just a unique index on your users table?
CREATE UNIQUE INDEX unq_uuid ON users (uuid);
Then you don't have to check, you just try to insert and it will return an error if it already exists.
This question already has answers here:
How to make scanning DB rows in Go DRY?
(1 answer)
How to call the Scan variadic function using reflection
(4 answers)
Closed 8 months ago.
I am reading all rows from postgresql database using golang. This method working perfectly, but I need to reorganise the code in a productive way. Any help is much appreciated.
Here is the code:
type Books struct {
Name string
ISBN string
Author string
PublishedOn string
}
func GetBooks() {
db := Connection() // COnnection to postgres database
var books []Books
rows, err := db.Query("SELECT * FROM books")
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
book := Books{}
err = rows.Scan(&book.Name, &book.ISBN, &book.Author, &book.PublishedOn)
books = append(books, book)
}
}
Here let us consider the struct has 20 fields and the row also have 20 columns. What is an effective method not to use &book.Name, &book.ISBN, &book.Author, &book.PublishedOn or some x number of columns and just include ONE single value
This question already has answers here:
Golang mgo getting empty objects
(1 answer)
Golang mgo Finding
(2 answers)
Closed 4 years ago.
I write the code with Go to get value from specify key, but it's return only `_idà value
from my code
func main() {
mongoDialInfo := &mgo.DialInfo{
Addrs: []string{"localhost:27017"},
Database: "person",
Username: "user",
Password: "user",
Timeout: 60 * time.Second,
}
session, err := mgo.DialWithInfo(mongoDialInfo)
if err != nil {
panic(err)
}
defer session.Close()
c := session.DB("person").C("person")
result := Person{}
name := "Bill"
err = c.Find(bson.M{"name": name}).Select(bson.M{"surname": 1 }).One(&result)
if err != nil {
panic(err)
}
fmt.Println("Surname is ", result)
}
and the result from code is
{ObjectIdHex("5b9bb0b39b5c3e5733e1c8f7") }
Please help me to fix it.
Problem description
I try to find documents stored in MongoDB using GO
Current state
For testing purposes I created a small test program that inserts data into MongoDB and immediately tries to query:
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type IndexedData struct {
ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
MyID int `json:"myid" bson:"myid"`
Content string `json:"content" bson:"content"`
}
func main() {
// Create a client
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
collection := session.DB("test").C("demo")
for index := 0; index < 10; index++ {
data := IndexedData{ID: bson.NewObjectId(), MyID: index, Content: "Some string"}
err = collection.Insert(data)
if nil != err {
panic(err)
} else {
fmt.Println("Successfully inserted")
}
}
for index := 9; index >= 0; index-- {
qry := collection.Find(IndexedData{MyID: index})
cnt, err := qry.Count()
if err != nil {
fmt.Println(fmt.Sprintf("%v - %s", index, err.Error()))
} else {
if cnt == 1 {
fmt.Println("Found")
} else {
if cnt > 1 {
fmt.Println(fmt.Sprintf("%v - Multiple: %v", index, cnt))
} else {
fmt.Println(fmt.Sprintf("%v - Not found", index))
}
}
}
}
qry := collection.Find(nil)
cnt, err := qry.Count()
if err != nil {
panic(err)
}
fmt.Println(fmt.Sprintf("%v items", cnt))
err = collection.DropCollection()
if err != nil {
panic(err)
}
}
Results
Actual
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
Successfully inserted
9 - Not found
8 - Not found
7 - Not found
6 - Not found
5 - Not found
4 - Not found
3 - Not found
2 - Not found
1 - Not found
0 - Not found
10 items
Expecting
I had expected to get 10 times Found
Update 1
I changed
qry := collection.Find(IndexedData{MyID: index})
to
qry := collection.Find(bson.M{"myid": index})
and I got a working sample.
The documentation states:
The document may be a map or a struct value capable of being marshalled with bson. The map may be a generic one using interface{} for its key and/or values, such as bson.M, or it may be a properly typed map.
I interpreted a properly annotated struct will work.
Question
How do I query for a document's property successfully?
I think you can open a issue.
I compared output of bson.Marshal for bson.M and your struct.
1 is fmt.Printf("%v\n", in) for your 36 row.
2 is fmt.Printf("%v\n", in) for that row
3 is otput println(string(e.out)) for that row
Output for e.out is different for struct and map. I suspect it's a bug.
Also I noticed that there is not some test which test struct. All tests use bson.M.
Thanks for a brilliant format of question!
I don't know anything about go but I would guess that you don't need the nil in the line qry := collection.Find(nil)