相关疑难解决方法(0)

Postgres:INSERT如果不存在

我正在使用Python写入postgres数据库:

sql_string = "INSERT INTO hundred (name,name_slug,status) VALUES ("
sql_string += hundred + ", '" + hundred_slug + "', " + status + ");"
cursor.execute(sql_string)
Run Code Online (Sandbox Code Playgroud)

但由于我的一些行是相同的,我收到以下错误:

psycopg2.IntegrityError: duplicate key value  
  violates unique constraint "hundred_pkey"
Run Code Online (Sandbox Code Playgroud)

如何编写'INSERT除非此行已存在'SQL语句?

我见过这样的复杂陈述:

IF EXISTS (SELECT * FROM invoices WHERE invoiceid = '12345')
UPDATE invoices SET billed = 'TRUE' WHERE invoiceid = '12345'
ELSE
INSERT INTO invoices (invoiceid, billed) VALUES ('12345', 'TRUE')
END IF
Run Code Online (Sandbox Code Playgroud)

但首先,这对于我需要的东西是否过度,其次,我怎样才能将其中一个作为简单的字符串执行?

python postgresql sql-insert

304
推荐指数
10
解决办法
27万
查看次数

如何在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万
查看次数

选择其他表中不存在的行

我有两个postgresql表:

table name     column names
-----------    ------------------------
login_log      ip | etc.
ip_location    ip | location | hostname | etc.
Run Code Online (Sandbox Code Playgroud)

我想得到每个login_log没有行的IP地址ip_location.
我尝试了这个查询,但它抛出了语法错误.

SELECT login_log.ip 
FROM login_log 
WHERE NOT EXIST (SELECT ip_location.ip
                 FROM ip_location
                 WHERE login_log.ip = ip_location.ip)
Run Code Online (Sandbox Code Playgroud)
ERROR: syntax error at or near "SELECT"
LINE 3: WHERE NOT EXIST (SELECT ip_location.ip`
Run Code Online (Sandbox Code Playgroud)

我也想知道这个查询(通过调整使其工作)是否是用于此目的的最佳性能查询.

sql postgresql null exists left-join

150
推荐指数
2
解决办法
18万
查看次数

如何在PostgreSQL中使用RETURNING和ON CONFLICT?

我在PostgreSQL 9.5中有以下UPSERT:

INSERT INTO chats ("user", "contact", "name") 
           VALUES ($1, $2, $3), 
                  ($2, $1, NULL) 
ON CONFLICT("user", "contact") DO NOTHING
RETURNING id;
Run Code Online (Sandbox Code Playgroud)

如果没有冲突,则返回如下内容:

----------
    | id |
----------
  1 | 50 |
----------
  2 | 51 |
----------
Run Code Online (Sandbox Code Playgroud)

但如果存在冲突,则不会返回任何行:

----------
    | id |
----------
Run Code Online (Sandbox Code Playgroud)

id如果没有冲突,我想返回新列,或者返回id冲突列的现有列.
可以这样做吗?如果是这样,怎么样?

sql postgresql upsert sql-returning

127
推荐指数
7
解决办法
4万
查看次数

psycopg2 忽略多行插入时的重复键违规

我正在执行以下代码,但是,偶尔会发生重复键冲突,整个插入将停止。如何忽略此类错误并让查询执行有效条目?

代码:

query_data = ','.join(cur.mogrify('(%s,%s)', row) for row in data)
insert_q = "INSERT INTO <table> VALUES {0};".format(query_data)

try:
   cur.execute(insert_q)                    
except psycopg2.Error:
   self.logger.exception('Database error')

con.commit()
Run Code Online (Sandbox Code Playgroud)

更新2:

我在下面发布了我自己的答案,解决了问题。它使用 Postgres 中新的 ON CONFLICT 语法。

更新1:

在 except 块内提交存在一个问题,但是,我发现,如果不这样做,所有其他插入都不会执行,并出现以下错误:

ERROR: current transaction is aborted, commands ignored until end of transaction block
Run Code Online (Sandbox Code Playgroud)

为了避免混淆,在 try except 之后添加了提交

python postgresql bulkinsert psycopg2

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

在PostgreSQL中使用EXCEPT子句

我试图使用该EXCEPT子句从表中检索数据.我希望获得table1除了存在的所有行之外的所有行table2.据我所知,以下内容不起作用:

CREATE TABLE table1(pk_id int, fk_id_tbl2 int);
CREATE TABLE table2(pk_id int);

Select fk_id_tbl2
FROM table1
Except
Select pk_id
FROM table2
Run Code Online (Sandbox Code Playgroud)

我可以使用的唯一方法EXCEPT似乎是从相同的表中选择或从不同的表中选择具有相同列名的列.

有人可以解释一下如何最好地使用explain子句吗?

sql postgresql except

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