相关疑难解决方法(0)

在PostgreSQL中重复更新时插入?

几个月前,我从Stack Overflow的答案中学到了如何使用以下语法在MySQL中一次执行多个更新:

INSERT INTO table (id, field, field2) VALUES (1, A, X), (2, B, Y), (3, C, Z)
ON DUPLICATE KEY UPDATE field=VALUES(Col1), field2=VALUES(Col2);
Run Code Online (Sandbox Code Playgroud)

我现在切换到PostgreSQL,显然这是不正确的.它指的是所有正确的表,所以我认为这是使用不同关键字的问题,但我不确定PostgreSQL文档中的哪个被覆盖.

为了澄清,我想插入几个东西,如果它们已经存在则更新它们.

sql postgresql upsert sql-merge

611
推荐指数
15
解决办法
40万
查看次数

如何在PostgreSQL中UPSERT(MERGE,INSERT ...在DUPLICATE UPDATE上)?

这里一个非常常见的问题是如何进行upsert,这是MySQL调用的INSERT ... ON DUPLICATE UPDATE,标准支持作为MERGE操作的一部分.

鉴于PostgreSQL不直接支持它(在第9.5页之前),你是如何做到这一点的?考虑以下:

CREATE TABLE testtable (
    id integer PRIMARY KEY,
    somedata text NOT NULL
);

INSERT INTO testtable (id, somedata) VALUES
(1, 'fred'),
(2, 'bob');
Run Code Online (Sandbox Code Playgroud)

现在,假设你想"UPSERT"的元组(2, 'Joe'),(3, 'Alan'),因此新表的内容是:

(1, 'fred'),
(2, 'Joe'),    -- Changed value of existing tuple
(3, 'Alan')    -- Added new tuple
Run Code Online (Sandbox Code Playgroud)

这是人们在讨论时所谈论的内容upsert.至关重要的是,任何方法在同一个表上存在多个事务时都必须是安全的 - 通过使用显式锁定,或以其他方式抵御由此产生的竞争条件.

关于PostgreSQL中的重复更新,Insert上广泛讨论了这个主题,但这是关于MySQL语法的替代品,随着时间的推移,它已经成长为一些无关的细节.我正在研究明确的答案.

这些技术对于"插入如果不存在,否则什么都不做"也很有用,即"插入...复制键忽略".

postgresql upsert insert-update sql-merge

246
推荐指数
5
解决办法
18万
查看次数

如何在 Postgres 中批量插入忽略过程中可能发生的所有错误?

我必须每小时在表中插入大量日志记录,我不会关心在此过程中发生的完整性错误或违规。

如果我禁用 autoCommit 并执行批量插入,则游标不会插入事务失败行以外的任何内容。有没有办法解决这个问题?

一种技巧是在应用程序级别处理此问题。我可以实现一个 n 大小的缓冲区并进行批量插入。如果该事务中的某些内容失败,则递归地为 buffer_first_half + buffer_second_half 重复插入

def insert(buffer):
    try:
        bulk_insert(buffer)
    except:
        connection.rollback()

        marker = len(buffer)/2

        insert(buffer[:marker])
        insert(buffer[marker:])
Run Code Online (Sandbox Code Playgroud)

但我真的希望是否可以使用任何 Postgres 的内置功能来实现?

postgresql

5
推荐指数
1
解决办法
2686
查看次数

忽略 CSV 导入时重复的行

我想知道是否可以?如果由于某种原因无法导入一行。重复的主键、错误的输入类型等是否可以被忽略并移动到下一行?

我明白了

ERROR:  duplicate key value violates unique constraint "team_pkey"
DETAIL:  Key (team)=(DEN) already exists.
CONTEXT:  COPY team, line 23: "DEN,Denver,Rockets,A"
Run Code Online (Sandbox Code Playgroud)

文件中有很多错误,而且文件很大,那么是否可以忽略无法插入的行?

csv postgresql

5
推荐指数
1
解决办法
9766
查看次数

PostgreSQL-插入记录的干净方法(如果它们不存在,则更新)

这是我的情况。我有一个带有一堆URL和与之关联的爬网日期的表。当我的程序处理URL时,我想插入一个具有爬网日期的新行。如果URL已经存在,我想将爬网日期更新为当前日期时间。对于MS SQL或Oracle,我可能为此使用MERGE命令。对于mySQL,我可能会使用ON DUPLICATE KEY UPDATE语法。

我可以在程序中执行多个查询,这些查询可能是线程安全的,也可能不是线程安全的。我可以编写一个具有各种IF ... ELSE逻辑的SQL函数。但是,为了试用以前从未使用过的Postgres功能,我正在考虑创建INSERT规则-类似于以下内容:

CREATE RULE Pages_Upsert AS ON INSERT TO Pages
  WHERE EXISTS (SELECT 1 from Pages P where NEW.Url = P.Url)
  DO INSTEAD
     UPDATE Pages SET LastCrawled = NOW(), Html = NEW.Html WHERE Url = NEW.Url;
Run Code Online (Sandbox Code Playgroud)

这实际上看起来很棒。从“代码可读性”的角度来看,它可能会失去一些意义,因为初次查看我的代码的人必须神奇地知道此规则,但是我想可以通过良好的代码注释和文档来解决。

此想法是否还有其他缺点,或者“您的想法糟透了,您应该/ this /方式代替”注释?如果那很重要,我将使用PG 9.0。

更新:查询计划,因为有人想要它:)

"Insert  (cost=2.79..2.81 rows=1 width=0)"
"  InitPlan 1 (returns $0)"
"    ->  Seq Scan on pages p  (cost=0.00..2.79 rows=1 width=0)"
"          Filter: ('http://www.foo.com'::text = lower((url)::text))"
"  ->  Result  (cost=0.00..0.01 rows=1 width=0)"
" …
Run Code Online (Sandbox Code Playgroud)

database postgresql rules upsert

4
推荐指数
1
解决办法
7246
查看次数

标签 统计

postgresql ×5

upsert ×3

sql-merge ×2

csv ×1

database ×1

insert-update ×1

rules ×1

sql ×1