Задать вопрос
  • Как применить ON CONFLICT для отслеживания изменений при INSERT?

    @nurzhannogerbek Автор вопроса
    Здравствуйте, Константин!

    Пытаюсь объединить два пункта в одну процедуру, как вы и советовали. Я написал такую процедуру:
    CREATE OR REPLACE PROCEDURE creator(SURVEY_ID uuid, EMPLOYEES VARCHAR[]) AS $FUNCTION$
    	BEGIN
    		DELETE FROM SURVEYS_EMPLOYEES_RELATIONSHIP
    		WHERE SURVEY_ID = SURVEY_ID
    		AND EMPLOYEE NOT IN (EMPLOYEES);
    		--
    		INSERT INTO SURVEYS_EMPLOYEES_RELATIONSHIP (SURVEY_ID, EMPLOYEE) 
    		SELECT SURVEY_ID SURVEY_ID, EMPLOYEE FROM UNNEST(ARRAY[EMPLOYEES]) EMPLOYEE
    		ON CONFLICT ON CONSTRAINT unique_key 
    		DO NOTHING;
    	END;
    $FUNCTION$ LANGUAGE plpgsql;


    Вызываю эту процедуру следующим образом:
    CALL creator('99c89a24-fff2-4cbc-a542-b1e956a352f9', ARRAY['NNogerbek@gmail.com', 'IKim@gmail.com'])


    При вызове происходит ошибка:
    SQL Error [42702]: ERROR: column reference "survey_id" is ambiguous
    Подробности: It could refer to either a PL/pgSQL variable or a table column.
    Где: PL/pgSQL function creator(uuid,character varying[]) line 3 at SQL statement


    Где в процедуре я ошибся?
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Леонид Николаев, тут не совсем CRON в чистом виде. Использую библиотеку github.com/mileusna/crontab которая запускает по таймеру скрипт. Заглянул под капот этой библиотеки и там используется как раз этот time.Ticker о котором вы упоминали. Могли бы уточнить в вашей функции чем из себя представляет o Obj и lp string указанные в качестве аргумента?!
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Леонид Николаев, Леонид, увеличивать количеств соединений не очень хорошая идея. Согласен. Прощу прощения, но ваша функция на отлавливание ошибок куда вставляется? Запутался малость. Данный скрипт я запускаю каждую минуту по CRON-у. Поэтому в течении минуты нужно обновлять записи в зависимости от активности пользователей.
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Сергей Тихонов, Сергей спасибо! Я на основе нашего последнего комментария создал процедуру. Выглядит она следующим образом.
    CREATE PROCEDURE tracker(CUSTOM_TIME VARCHAR) AS $FUNCTION$
    	BEGIN
    		UPDATE SURVEYS SET CONDITION = 3 WHERE BLOCKED AND CONDITION = 2 AND CUSTOM_TIME > END_PERIOD;
    		UPDATE SURVEYS SET BLOCKED = TRUE WHERE NOT BLOCKED AND CONDITION = 2 AND CUSTOM_TIME BETWEEN START_PERIOD AND END_PERIOD;
    	END;
    $FUNCTION$ LANGUAGE plpgsql;


    Вызов процедуры:
    CALL tracker('2019-03-29 16:37:00');

    При попытке вызвать эту процедуру появляется ошибка:
    SQL Error [42883]: ERROR: operator does not exist: character varying > timestamp without time zone
    Подсказка: No operator matches the given name and argument types. You might need to add explicit type casts.
    Где: PL/pgSQL function tracker(character varying) line 3 at SQL statement


    Ругается на проверку времени в запросе. Что я делаю в запросе не правильно?
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Леонид Николаев, Леонид как раз на основе этого опроса написал такой код. Можете пожалуйста на него взглянуть и сказать какие проблемы вы видите? Если честно не знаю как текущий код поменять на один запрос. Что можете посоветовать? Я правильно понимаю, если к примеру я делаю 200 запросов на update по сути выполняются 200 коннекшенов? Поэтому и возникал warning pq: sorry, too many clients already. Предпологается что в таблице с которой работаю сейчас будет всегда 200-300 записей. На стороне БД увеличил количество коннекшенов на 500. Сейчас при 200 запросов на update warning-ов не возникает.

    var Tracker = func() {
    	// Инициализируем массив.
    	var products [] models.Product
    
    	// Получаем список продуктов из базы данных.
    	if err := db.Find(&products).Error; err != nil {
    		log.Fatal(err)
     		return
    	}
    
    	// Создаем канал.
    	channel := make(chan models.Product, len(products))
    
    	// Запускаю 5 воркеров.
    	for w := 1; w <= 5; w++ {
    		go Worker(worker, channel, currentTime)
    	}
    
    	// Устанавливаю емкость канала.
    	for j := 1; j <= len(products); j++ {
    		channel <- surveys[i]
    	}
    	close(channel)
    }
    
    func Worker(workerID int, channel <- chan models.BetaSurvey, currentTime time.Time) {
    	fmt.Println("worker", workerID, "started  job")
    
    	for product := range channel {
    		startPeriod := product.StartPeriod.UTC()
    		endPeriod := product.EndPeriod.UTC()
    
    		if product.Blocked == false {
    			if startPeriod.Before(currentTime) && endPeriod.After(currentTime) {
    				if err := database.DBGORM.Find(&product).Error; err != nil {
    					log.Println(err)
    					return
    				}
    				if err := database.DBGORM.Model(&product).Update("blocked", true).Error; err != nil {
    					log.Println(err)
    					return
    				}
    			}
    		} else if product.Blocked == true {
    			if endPeriod.Before(currentTime) {
    				if err := database.DBGORM.Find(&product).Error; err != nil {
    					log.Println(err)
    					return
    				}
    				if err := database.DBGORM.Model(&product).Update("condition", 3).Error; err != nil {
    					log.Println(err)
    					return
    				}
    			}
    		}
    	}
    
    	fmt.Println("worker", workerID, "finished  job")
    }
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Сергей Тихонов, Сергей, спасибо за совет! Если честно не понимаю, как текущий код под один запрос переписать. Можете пожалуйста подсказать?

    Я правильно понимаю, что воркеры и канали нужно создать следующим образом:
    var Tracker = func() {
    	// Инициализируем массив.
    	var products [] models.Product
    
    	// Получаем список продуктов из базы данных.
    	if err := db.Find(&products).Error; err != nil {
    		log.Fatal(err)
     		return
    	}
    
    	// Создаем канал.
    	channel := make(chan models.Product, len(products))
    
    	// Запускаю 5 воркеров.
    	for w := 1; w <= 5; w++ {
    		go worker(w, channel)
    	}
    
    	// Устанавливаю емкость канала.
    	for j := 1; j <= 10; j++ {
    		channel <- j
    	}
    	close(channel)
    }
    
    func Worker(id int, channel <- chan models.Product) {
        for product := range channel {
            // Остальной код
        }
    }
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Здравствуйте, Леонид! Спасибо за ваш ответ. На самом деле здесь лишь выдуманный пример, как я понимаю неудачный, за что извиняюсь. Здесь я хотел узнать узкие места, подводные камни, которые есть в плане многопоточности. Получается вот код который я использую в данный момент. Не уверен, что в нем можно одним SQL запросом это сделать, как так проверяется вхождение текущего времени в период (startPeriod, endPeriod).

    ***
    currentTime := time.Now().In(timezone).UTC().Add(6 * time.Hour)
    
    for _, product := range products {
    	go Checker(product, currentTime)
    }
    ***
    
    func Checker(product models.Product, currentTime time.Time)  {
    	startPeriod := product.StartPeriod.UTC()
    	endPeriod := product.EndPeriod.UTC()
    
    	if product.Blocked == false {
    		if startPeriod.Before(currentTime) && endPeriod.After(currentTime) {
    			if err := database.DBGORM.Find(&product).Error; err != nil {
    				log.Println(err)
    				return
    			}
    			if err := database.DBGORM.Model(&product).Update("blocked", true).Error; err != nil {
    				log.Println(err)
    				return
    			}
    		}
    	} else if product.Blocked == true {
    		if endPeriod.Before(currentTime) {
    			if err := database.DBGORM.Find(&product).Error; err != nil {
    				log.Println(err)
    				return
    			}
    			if err := database.DBGORM.Model(&product).Update("condition", 3).Error; err != nil {
    				log.Println(err)
    				return
    			}
    		}
    	}
    }


    В данный момент я протестил данный код на 100 и все отработало без проблем, когда тестил на 200 записях появлялись warning-и типо pq: sorry, too many clients already. Это случаем не из-за тех самых транзакций о которых вы говорите? При этом в базе все изменилось, правда не все сразу а как-то по частям, некоторые с опозданием на секунду. Аномалий не заметил других. Сколько в теории горутины можно создать? Это зависит от машины, я прав?

    Могли бы пожалуйста привести пример с воркерами, чтобы разговор был предметным?
  • Как в GO через многопоточность обрабатывать данные из базы данных?

    @nurzhannogerbek Автор вопроса
    Здравствуйте, Сергей! Спасибо за ваш ответ. На самом деле здесь лишь выдуманный пример, как я понимаю неудачный, за что извиняюсь. Здесь я хотел узнать узкие места, подводные камни есть в плане многопоточности. Получается вот код который я использую в данный момент. Не уверен, что в нем можно одним SQL запросом это сделать, как так проверяется вхождение текущего времени в период (startPeriod, endPeriod).

    ***
    currentTime := time.Now().In(timezone).UTC().Add(6 * time.Hour)
    
    for _, product := range products {
    	go Checker(product, currentTime)
    }
    ***
    
    func Checker(product models.Product, currentTime time.Time)  {
    	startPeriod := product.StartPeriod.UTC()
    	endPeriod := product.EndPeriod.UTC()
    
    	if product.Blocked == false {
    		if startPeriod.Before(currentTime) && endPeriod.After(currentTime) {
    			if err := database.DBGORM.Find(&product).Error; err != nil {
    				log.Println(err)
    				return
    			}
    			if err := database.DBGORM.Model(&product).Update("blocked", true).Error; err != nil {
    				log.Println(err)
    				return
    			}
    		}
    	} else if product.Blocked == true {
    		if endPeriod.Before(currentTime) {
    			if err := database.DBGORM.Find(&product).Error; err != nil {
    				log.Println(err)
    				return
    			}
    			if err := database.DBGORM.Model(&product).Update("condition", 3).Error; err != nil {
    				log.Println(err)
    				return
    			}
    		}
    	}
    }


    В данный момент я протестил на 100 записях данный код и все отработало без проблем, когда тестил на 200 записях появлялись warning-и типо pq: sorry, too many clients already. При этом в базе все изменилось, чуть чуть с опозданием. Сколько в теории горутины можно создать? Это зависит от машины, я прав?
  • Как использовать массив в запросе к базе данных из Golang?

    @nurzhannogerbek Автор вопроса
    Даша Циклаури, спасибо, Дарья! Я сформировал шаблон запроса благодаря Вам. У меня такой вопрос. Сейчас получаю такое сообщение: sql: expected 3 arguments, got 1. Получается в этом выражении .Query(stmt, args)args это массив. Нужно сюда каждый элемент массива через запятую вставить. Я правильно понимаю? Могли бы пожалуйста что-нибудь посоветовать?
  • Как использовать массив в запросе к базе данных из Golang?

    @nurzhannogerbek Автор вопроса
    Я ради эксперимента запустил такой код и он отработал. C :1, :2, :3 почему-то не работает.
    .Query("SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORGWHERE ORGANIZATION_ID IN (:value1, :value2, :value3)", "27625", "27626", "27627")


    То есть ошибка в шаблоне (переменная smtp). Могли бы пример показать по strings.Builder пожалуйста?!
  • Как использовать массив в запросе к базе данных из Golang?

    @nurzhannogerbek Автор вопроса
    Алексей Ступеньков, что именно вас смущает? Ради тестов, я пробовал явно прописал запрос и он работает. stmt - это шаблон запроса, а args это значения, которые должны быть в запросе.

    .Query("SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value1, :value2, :value3)", "27625", "27626", "27627")


    У меня шаблон запроса (переменная stmt) получился следующим:
    SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value,:value,:value)


    А должен быть таким на мой взгляд:
    SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value1,:value2,:value3)


    Не в этом ли кроется ошибка? Как добиться следующего результата?
  • Как использовать массив в запросе к базе данных из Golang?

    @nurzhannogerbek Автор вопроса
    Здравствуйте! Я правильно понимаю, что вы советуете добавить три точки? Я их добавил, но ошибка схожая:
    sql: expected 1 arguments, got 3

    У меня шаблон запроса (переменная stmt) получился следующим:
    SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value,:value,:value)


    А должен быть таким на мой взгляд:
    SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value1,:value2,:value3)


    Не в этом ли кроется ошибка? Как добиться следующего результата?
  • Как использовать массив в запросе к базе данных из Golang?

    @nurzhannogerbek Автор вопроса
    Здравствуйте! Изменил, как вы советовали. Ошибка та же.

    Я заметил следующее. У меня шаблон запроса (переменная stmt) получился следующим:
    SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value,:value,:value)


    А должен быть таким на мой взгляд:
    SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORG WHERE ORGANIZATION_ID IN (:value1,:value2,:value3)


    Не в этом ли кроется ошибка? Как добиться следующего результата?
  • SequelizeConnectionError в Node.js приложении?

    @nurzhannogerbek Автор вопроса
    Василий, здравствуйте!

    Вообщем через некоторое время после того как задал этот вопрос появилось такая ошибка:
    User 'mysql_user' has exceeded the 'max_user_connections' resource (current value: 20)


    Погуглив заметил, что есть решение на стороне БД. Можно увеличить количество подключений, вроде как следующим образом set global max_connections = 200; к примеру. Данное решение скорее всего решит проблему лишь временно и через некоторое время проблема повторится.

    Мне кажется в самом приложении нужно закрывать connection. Вы не в курсе как это делается в Sequelize?
  • Как исправить проблему docker: Error response from daemon: oci runtime error: container_linux.go?

    @nurzhannogerbek Автор вопроса
    Владислав Фурсов, вообщем установил в Docker image xgo как говорится в документации:
    docker pull karalabe/xgo-latest

    Далее зашел в директорию проекта и выполнил команду xgo -targets linux/amd64 . Выдал такой message:
    Checking docker installation...
    Client:
     Version:       18.03.0-ce
     API version:   1.37
     Go version:    go1.9.4
     Git commit:    0520e24302
     Built: Fri Mar 23 08:31:36 2018
     OS/Arch:       windows/amd64
     Experimental:  false
     Orchestrator:  swarm
    
    Server: Docker Engine - Community
     Engine:
      Version:      18.09.3
      API version:  1.39 (minimum version 1.12)
      Go version:   go1.10.8
      Git commit:   774a1f4
      Built:        Thu Feb 28 06:40:51 2019
      OS/Arch:      linux/amd64
      Experimental: false
    
    Checking for required docker image karalabe/xgo-latest... found.
    Cross compiling application...
    docker: Error response from daemon: invalid mode: /build.
    See 'docker run --help'.
    2019/03/12 21:09:13 Failed to cross compile package: exit status 125.


    Как видите daemon ругается. Что происходит на ваш взгляд?
  • Как исправить проблему docker: Error response from daemon: oci runtime error: container_linux.go?

    @nurzhannogerbek Автор вопроса
    Вообщем установил Docker Toolbox на Windows. Установил xgo, а котором вы говорили. Что дальше? Как билдить проект на нем можете подсказать?
  • Как исправить проблему docker: Error response from daemon: oci runtime error: container_linux.go?

    @nurzhannogerbek Автор вопроса
    Владислав Фурсов, Файл application удалил. При попытке создать image на последний Dockerfile ругается на все мои пакеты:
    main.go:9:2: cannot find package "application/database" in any of:
            /go/src/application/vendor/application/database (vendor tree)
            /usr/local/go/src/application/database (from $GOROOT)
            /go/src/application/database (from $GOPATH)
    main.go:10:2: cannot find package "application/routes" in any of:
            /go/src/application/vendor/application/routes (vendor tree)
            /usr/local/go/src/application/routes (from $GOROOT)
            /go/src/application/routes (from $GOPATH)
    main.go:11:2: cannot find package "application/utils" in any of:
            /go/src/application/vendor/application/utils (vendor tree)
            /usr/local/go/src/application/utils (from $GOROOT)
            /go/src/application/utils (from $GOPATH)
    controllers/factor.go:10:2: cannot find package "application/models" in any of:
            /go/src/application/vendor/application/models (vendor tree)
            /usr/local/go/src/application/models (from $GOROOT)
            /go/src/application/models (from $GOPATH)
    vendor/gopkg.in/goracle.v2/conn.go:33:2: cannot find package "github.com/pkg/errors" in any of:
            /go/src/application/vendor/github.com/pkg/errors (vendor tree)
            /usr/local/go/src/github.com/pkg/errors (from $GOROOT)
            /go/src/github.com/pkg/errors (from $GOPATH)
    routes/routes.go:5:2: cannot find package "application/controllers" in any of:
            /go/src/application/vendor/application/controllers (vendor tree)
            /usr/local/go/src/application/controllers (from $GOROOT)
            /go/src/application/controllers (from $GOPATH)
  • Как исправить проблему docker: Error response from daemon: oci runtime error: container_linux.go?

    @nurzhannogerbek Автор вопроса
    Владислав Фурсов, Касательно вашего последнего комментария. Контейнер создался успешно. В логах контейнера возвращает список со структурой проекта. Все скопировалось правильно:
    drwxr-xr-x. 10 root root      222 Mar 12 14:07 .
    drwxrwxrwx.  4 root root       43 Mar 12 14:07 ..
    -rw-r--r--.  1 root root      326 Mar  7 11:18 .env
    drwxr-xr-x.  7 root root      150 Mar 12 09:16 .git
    -rw-r--r--.  1 root root       12 Mar  3 15:09 .gitignore
    drwxr-xr-x.  4 root root      192 Mar 12 09:16 .idea
    -rw-r--r--.  1 root root      804 Mar 12  2019 Dockerfile
    -rw-r--r--.  1 root root     2603 Mar 12 05:14 README.md
    drwxr-xr-x.  2 root root      173 Mar 12 09:16 controllers
    drwxr-xr-x.  2 root root       44 Mar 12 09:16 database
    -rw-r--r--.  1 root root     1951 Mar  7 11:32 main.go
    drwxr-xr-x.  2 root root       93 Mar 12 09:16 models
    -rw-r--r--.  1 root root 16507975 Mar 12 08:47 application
    drwxr-xr-x.  2 root root       23 Mar 12 09:16 routes
    drwxr-xr-x.  2 root root       22 Mar 12 09:16 utils
    drwxr-xr-x.  3 root root       22 Mar 12 09:16 vendor


    На счет вашего предпоследнего комментария. При попытке создать image появилось ошибка:
    Step 11/13 : RUN go build -o /application .
     ---> Running in 98a045250847
    main.go:9:2: cannot find package "application/database" in any of:
            /go/src/application/vendor/application/database (vendor tree)
            /usr/local/go/src/application/database (from $GOROOT)
            /go/src/application/database (from $GOPATH)
    main.go:10:2: cannot find package "application/routes" in any of:
            /go/src/application/vendor/application/routes (vendor tree)
            /usr/local/go/src/application/routes (from $GOROOT)
            /go/src/application/routes (from $GOPATH)
    main.go:11:2: cannot find package "application/utils" in any of:
            /go/src/application/vendor/application/utils (vendor tree)
            /usr/local/go/src/application/utils (from $GOROOT)
            /go/src/application/utils (from $GOPATH)


    Что думаете по этому поводу?