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", "другое значение", "и т. Д.", Чтобы вы могли видеть двойные кавычки против одинарных кавычек.

Другие вопросы по тегам