我进行了广泛的搜索,但我无法解决这个简单的问题。我使用nodejs编程,并使用pg-promise将我的JSON文件动态存储到postgres 9.4.11数据库中(我不允许升级数据库)。我的JSON每列包含大约100列,我已经将其正确地解析为三个对象。1.字段2.列3.表Pg-promise在我这样做的时候可以完美地工作:
//-- 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开始可用。
我的查询每次执行大约2,000个行插入,我对此很满意。
我在这方面还是个新手,我希望在我的谷歌时间里,我忽略了直接的解决方案。
我见过的最接近的解决方案是存储过程,但我不确定如何实现它。
求求你,stackoverflow,你可能是我唯一的希望!
我只想确保在id1、uid2和xid3上匹配的每一行都不会被插入到我的postgres数据库中。
发布于 2017-11-15 06:20:06
所以我学到了一些关于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-promise将postgres查询拼接在一起似乎有些老生常谈,但这是我发现的使用for循环加载数百行、数百列宽的数据的最佳方法。
注意,我有一个值数组,但我把它们写成了'google.com',‘另一个值’,'etc...‘这样你就会看到双引号和单引号。
https://stackoverflow.com/questions/47025129
复制相似问题