pg-обещание поддержать на postgresql 9.4.11
Я много искал и не смог решить эту простую проблему. Я программирую на nodejs и использую pg-обещание для динамического сохранения моего JSON-файла в базе данных postgres 9.4.11 (мне не разрешено обновлять БД). Мой JSON содержит около ста столбцов каждый, и я правильно разбил его на три объекта. 1. поля 2. столбцы 3. таблицы Pg-обещание работает ОТЛИЧНО, когда я делаю это:
//-- connection details would be up here const db = pgp (conn);--
//Insert statement is below
for (var i=0; i<Object.keys(fields).length; i++){
const data = [fields[i]];
const cs = new pgp.helpers.ColumnSet(columns[i]);
const table = new pgp.helpers.TableName(tables[i],"public");
const insert = pgp.helpers.insert(data,cs,table);
db.none(insert)
.then(data => {
console.log("Success! Record inserted for " + table);
})
.catch(error => {
//error
console.log("ALERT!!! Something went wrong with Record in table " + table);
});
}
Но, конечно, я на postgresql 9.4.11 и не могу использовать простое:
const insert = pgp.helpers.insert(data,cs,table) + " ON CONFLICT (id1, uid2, xid3) DO NOTHING";
выполнить вставку ТОЛЬКО новых предметов, потому что UPSERTS доступны только начиная с 9.5.
Мой запрос выполняет около 2000 вставок строк за цикл, и я доволен этим.
Я довольно новичок в этом, и я надеюсь, что, возможно, в часы поисков я пропустил прямолинейное решение.
Самое близкое разрешение, которое я видел, - это хранимая процедура, но я не уверен, как бы это реализовать.
Пожалуйста, stackru, вы можете быть моей единственной надеждой!
Я просто хочу убедиться, что каждая строка, соответствующая id1, uid2 и xid3, не будет вставлена в мою базу данных postgres.
1 ответ
Итак, я узнал кое-что о postgres. Но во-первых, это код, который наконец-то сработал для меня:
for (var i=0; i<Object.keys(fields).length; i++){
const data = [fields[i]];
const cs = new pgp.helpers.ColumnSet(columns[i]);
const table = new pgp.helpers.TableName(tables[i],"public");
const insert = pgp.helpers.insert(data,cs,table);
db.none( 'BEGIN WORK; LOCK TABLE public.'
+ tables[i] + ' IN SHARE ROW EXCLUSIVE MODE; '
+ 'INSERT INTO public.'+tables[i]+ ' ('+ columns[i]+')'
+ 'SELECT 'google.com','another value', 'etc...' WHERE NOT EXISTS(SELECT 1 FROM public.'
+tables[i] +' WHERE id1 ='+fields[i].id1
+' AND uid2 ='+fields[i].uid2
+' AND xid3 ='+fields[i].xid3 +');'
+ 'COMMIT WORK;' )
}
Итак, я узнал, что postgres не видит элементы внутри двойных кавычек как значения, а как столбцы. Поэтому мне пришлось взять массив значений, убрать двойные кавычки и заменить их одинарными, что позволило postgres принять запрос.
Такое использование pg-обещания для объединения запросов postgres может показаться хакерским, но это лучший способ работы с моими данными с использованием цикла for для загрузки сотен строк шириной в сотни столбцов.
Обратите внимание, у меня есть массив значений, но я записал их как "google.com", "другое значение", "и т. Д.", Чтобы вы могли видеть двойные кавычки против одинарных кавычек.