Alexander
мммм
Alexander
а что там строить? INSERT INTO table(field1, field2,...) VALUES (?, ?, ...)
Alexander
?
Konstantin
?
INSERT INTO table(field1, field2,...) VALUES (?, ?, ...), (?,?, ...) ...
Konstantin
И так далее
Alexander
но этот драйвер же так не работает
Alexander
var ( tx, _ = connect.Begin() stmt, _ = tx.Prepare("INSERT INTO example (country_code, os_id, browser_id, categories, action_day, action_time) VALUES (?, ?, ?, ?, ?, ?)") ) defer stmt.Close() for i := 0; i < 100; i++ { if _, err := stmt.Exec( "RU", 10+i, 100+i, clickhouse.Array([]int16{1, 2, 3}), time.Now(), time.Now(), ); err != nil { log.Fatal(err) } } if err := tx.Commit(); err != nil { log.Fatal(err) }
Konstantin
зачем так делать?
Сам увидел этот код только вчера) tableName = "pool_" + tableName + "_main" start := time.Now() query := "INSERT INTO " + dbName + "." + tableName + " (" log.Println("Try insert into ", tableName) for _, v := range fields { query += v + "," } query = query[0:len(query)-1] + ") VALUES " + forPrep[:len(forPrep)-1] log.Println("Try start transaction") transaction, errTx := c.Link.Begin() if errTx != nil { log.Println("Transaction begin error: ", errTx) return } log.Println("Transaction started") stmt, err := transaction.Prepare(query) if err != nil { log.Println(err) } defer stmt.Close() log.Println("Preparing is complete ", time.Since(start)) t := time.Now() fldCntr := 0 var valuesPrepared []interface{} for _, v := range values { valuesPrepared = append(valuesPrepared, v) fldCntr++ if fldCntr >= len(fields)-1 { fldCntr = 0 var concatPrepared []interface{} ms := time.Since(t).Microseconds() x := rand.Intn(1000000) hash := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%v", ms)+fmt.Sprintf("%v", time.Now())+fmt.Sprintf("%v", x)))) concatPrepared = append(concatPrepared, hash) concatPrepared = append(concatPrepared, valuesPrepared...) stmt.Exec(concatPrepared...) valuesPrepared = []interface{}{} } } log.Println("Try commit") txError := transaction.Commit() log.Println("Commit done") if txError != nil { log.Println("Transaction end error: ", txError) } log.Println("End insert")
Bagasl
Alexander
ахаха)
Alexander
да тут как бы понятно чем пахнет
Konstantin
да тут как бы понятно чем пахнет
Пахнет сеньерским кодом
Konstantin
)))
Alexander
мне еще нравится, что мы внутри транзакции делаем недешевые вычисления
Bagasl
Пахнет сеньерским кодом
strings.Builder гугли срочно
Alexander
но опять же, надо сначала профилировать, потом уже оптимизировать. в go прекрасный инструмент для этого
Konstantin
Спасибо! Буду разгребать
Alexander
это лучше переписать: 1. Формируем данные (можно и 10к, не всегда при вставке 1М сильно быстрее) 2. Опционально сортируем по primary key 3. стартуем транзакцию 4. готовим простой стейтмент 5. обходим данные из пункта 1 и по строке вставляем стейтмент 6. коммитим
Alexander
если уже после профайлинга, оптимизации и такого переписывания будет упираться во вставку, то пиши
Konstantin
если уже после профайлинга, оптимизации и такого переписывания будет упираться во вставку, то пиши
А как вообще на Go работается? Я просто мидл PHP, думаю на Go перебраться потихоньку Вот задачки дали недавно, переписать
Konstantin
У кого-нибудь есть проекты свои на github? Интересует построение структуры проектов
Null
➡️ Связанный список в Golang https://uproger.com/svyazannyj-spisok-v-golang/ @Golang_google
ZeroX
А нафига они нужны если есть interface{}
Bagasl
А нафига они нужны если есть interface{}
Функция sum к примеру. На интерфейсах постоянно тип придется приводить обратно
Bagasl
Как в функции, так и при возврате из нее
Aртем
Как задать прокси для get запросов при парсинге?
Anonymous
указываешь в среде прокси
Anonymous
и все
Alexander
а как в одном процессе несколько разных прокси юзать?
Alexander
тогда
Alexander
что за нереалистичный кейс, когда у тебя одна прокся на все?
Anonymous
хорошо, тогда создаешь переменные proxy1, err := парсишь тут первый прокси proxy2, err := парсишь второй прокси потом указываешь какой тебе нужен
Anonymous
он не говорил, что ему нужна многозадачность
Alexander
Всем привет! Вопросец возник. У меня в бд лежит json разного формата, мне нужно его вывести в ответ на запрос(работаю через gin) но он эскейпает все кавычки и выводить как строку. Как сериализовать эту строку и вывести как json объект?
Anonymous
фронт посылает запрос, а ты с бэка отвечаешь жсоном?
Anonymous
json.NewEncoder(w).Encode(YourResponse)
Anonymous
можешь в переменную добавить, тогда не надо будет каждый раз врайтера указывать
Alexander
json.NewEncoder(w).Encode(YourResponse)
r.GET("/request-info/:requestId", func(c *gin.Context) { requestId := c.Params.ByName("requestId") requestInfo := getRequestInfo(requestId) jsonResponse := json.NewEncoder(c.Writer).Encode(requestInfo) c.JSON(http.StatusOK, jsonResponse) })
Alexander
так имеешь в виду?
Alexander
У меня такой объект сейчас возвращается: { "req_id": "5678947c-deeb-4c39-9b2e-971affc35358", "req_action": "geteod", "req_method": "", "req_path": "", "req_data": "{\"Action\":\"geteod\",\"apiVersion\":\"v0.6\",\"acceptLanguage\":\"EN\",\"X-Request-ID\":\"5678947c-deeb-4c39-9b2e-971affc35358\"}", "res_data": "{\"version\":\"v0.6\",\"isOperationDayOpen\":1,\"iabsInfo\":{\"errorCode\":0,\"httpResponseCode\":200}}", "state": "1", "created_on": "2020-04-13T11:15:49+05:00", "x_initiator": "", "x_channel": "" }
Alexander
мне нужно поля req_data и res_data сериализовать
Alexander
da
Не помогло(
Anonymous
а почему изначальный вариант не работает?
Alexander
в структуре поля нужно как-то типизировать ? Чтобы не просто стринг были
Anonymous
c.JSON() вроде бы сразу сериализует
Alexander
c.JSON() вроде бы сразу сериализует
Там когда маршализация происходит, он видит эти 2 поля как стринговые, видит в них двойные кавычки и экранирует. Может мне эти поля отдельно надо сериализовать?
Anonymous
такая?
Alexander
да
Anonymous
так тебе нужно указать, json:"name"
Alexander
так тебе нужно указать, json:"name"
type LogData struct { ReqId string json:"req_id" ReqAction string json:"req_action" ReqMethod string json:"req_method" ReqPath string json:"req_path" ReqData string json:"req_data" ResData string json:"res_data" State string json:"state" CreatedOn string json:"created_on" XInitiator string json:"x_initiator" XChannel string json:"x_channel" }
Anonymous
а
Anonymous
тогда попробуй
Anonymous
test, err := json.Marshal(ClientData) c.JSON(200, test)
Alexander
Он в байты переводит. Надо делать string() ?
Alexander
ReqData string json:"req_data" ResData string json:"res_data" сделай типа interface{} и десериализуй в них
Alexander
потом уже целиком весь объект сериализуй
Alexander
ReqData string json:"req_data" ResData string json:"res_data" сделай типа interface{} и десериализуй в них
ниче что у меня поля там всегда разные ? просто interface{} пойдет?
Alexander
вот именно
Anonymous
Он в байты переводит. Надо делать string() ?
c.JSON(200, gin.H{ "response": string(ClientData), })
Anonymous
я так делал
Alexander
это конечно немного накладно, можно просто туда какие-то строки, которые будешь потом заменять
Alexander
https://pkg.go.dev/encoding/json#RawMessage
Alexander
вот, кстати
Alexander
{ "response": { "req_id": "5678947c-deeb-4c39-9b2e-971affc35358", "req_action": "geteod", "req_method": "", "req_path": "", "req_data": "IntcIkFjdGlvblwiOlwiZ2V0ZW9kXCIsXCJhcGlWZXJzaW9uXCI6XCJ2MC42XCIsXCJhY2NlcHRMYW5ndWFnZVwiOlwiRU5cIixcIlgtUmVxdWVzdC1JRFwiOlwiNTY3ODk0N2MtZGVlYi00YzM5LTliMmUtOTcxYWZmYzM1MzU4XCJ9Ig==", "res_data": "IntcInZlcnNpb25cIjpcInYwLjZcIixcImlzT3BlcmF0aW9uRGF5T3BlblwiOjEsXCJpYWJzSW5mb1wiOntcImVycm9yQ29kZVwiOjAsXCJodHRwUmVzcG9uc2VDb2RlXCI6MjAwfX0i", "state": "1", "created_on": "2020-04-13T11:15:49+05:00", "x_initiator": "", "x_channel": "" } }
Alexander
c.JSON(http.StatusOK, gin.H{"response": requestInfo})
Alexander
result.ReqData, _ = json.Marshal(reqData) result.ResData, _ = json.Marshal(resData)
Anonymous
ну так получилось же
Alexander
не то, но я скинул уже лучше вариант
Anonymous
кстати тебя устраивает такой формат времени?
Alexander
не то, но я скинул уже лучше вариант
Мне как RawMessage передавать весь объект или только те 2 поля?
Alexander
Anonymous
2 поля