我有此表(由Django生成):
CREATE TABLE feeds_person (
id serial PRIMARY KEY,
created timestamp with time zone NOT NULL,
modified timestamp with time zone NOT NULL,
name character varying(4000) NOT NULL,
url character varying(1000) NOT NULL,
email character varying(254) NOT NULL,
CONSTRAINT feeds_person_name_ad8c7469_uniq UNIQUE (name, url, email)
);
我试图INSERT
通过ON CONFLICT
子句批量插入很多数据。
皱纹是,我需要得到id
的背都行的,无论他们是已经存在与否。
在其他情况下,我会做类似的事情:
INSERT INTO feeds_person (created, modified, name, url, email)
VALUES blah blah blah
ON CONFLICT (name, url, email) DO UPDATE SET url = feeds_person.url
RETURNING id
执行UPDATE
原因会使该语句返回该id
行的。除此之外,它不适用于此表。我认为这是行不通的,因为我拥有多个唯一的字段,而在其他情况下,我使用此方法时只有一个唯一的字段。
尝试通过Django的游标运行SQL时出现此错误:
django.db.utils.ProgrammingError: ON CONFLICT DO UPDATE command cannot affect row a second time
HINT: Ensure that no rows proposed for insertion within the same command have duplicate constrained values.
如何在此表中批量插入并获取插入的ID和现有ID?
你得到的错误:
ON CONFLICT DO UPDATE命令不能再次影响行
表示你试图在单个命令中多次向上插入同一行。换句话说:你(name, url, email)
的VALUES
名单上有骗子。折叠重复项(如果可以的话),它应该可以工作。但是你将不得不决定从每组重复中选择哪一行。
INSERT INTO feeds_person (created, modified, name, url, email)
SELECT DISTINCT ON (name, url, email) *
FROM (
VALUES
('blah', 'blah', 'blah', 'blah', 'blah')
-- ... more
) v(created, modified, name, url, email) -- match column list
ON CONFLICT (name, url, email) DO UPDATE
SET url = feeds_person.url
RETURNING id;
由于我们现在使用独立VALUES表达式,因此你必须为非默认类型添加显式类型转换。喜欢:
VALUES
(timestamptz '2016-03-12 02:47:56+01'
, timestamptz '2016-03-12 02:47:56+01'
, 'n3', 'u3', 'e3')
...
你的timestamptz列需要显式类型转换,而字符串类型可以使用default操作text。(你仍然可以立即投射varchar(n)。)
有一些方法可以确定从每个重复对象中选择哪一行:
在每个GROUP BY组中选择第一行?
没错,(当前)没有办法在子句中获取排除的行RETURNING
。我引用Postgres Wiki:
请注意,RETURNING这不会使“ EXCLUDED.*
”别名可见UPDATE(只有通用的“ TARGET.*
”别名在此处可见)。人们认为这样做会为简单,常见的情况[30]带来烦人的歧义,却几乎没有好处。在将来的某个时候,我们可能会寻求一种方法来公开是否 RETURNING
插入和更新了-projected元组,但这可能不需要使它成为该功能的首次提交迭代[31]。
但是,你不应该更新不应更新的行。空更新几乎与常规更新一样昂贵-可能会有意想不到的副作用。你并非一开始就完全需要UPSERT,你的案例看起来更像是“ SELECT或INSERT”。有关:
SELECT或INSERT函数是否易于出现竞争状况?
插入一组行的一种更干净的方法是使用修改数据的CTE:
WITH val AS (
SELECT DISTINCT ON (name, url, email) *
FROM (
VALUES
(timestamptz '2016-1-1 0:0+1', timestamptz '2016-1-1 0:0+1', 'n', 'u', 'e')
, ('2016-03-12 02:47:56+01', '2016-03-12 02:47:56+01', 'n1', 'u3', 'e3')
-- more (type cast only needed in 1st row)
) v(created, modified, name, url, email)
)
, ins AS (
INSERT INTO feeds_person (created, modified, name, url, email)
SELECT created, modified, name, url, email FROM val
ON CONFLICT (name, url, email) DO NOTHING
RETURNING id, name, url, email
)
SELECT 'inserted' AS how, id FROM ins -- inserted
UNION ALL
SELECT 'selected' AS how, f.id -- not inserted
FROM val v
JOIN feeds_person f USING (name, url, email);
增加的复杂性应该为大表支付INSERT规则和SELECT例外。
最初,我NOT EXISTS在最后一个谓词上添加了谓词,SELECT以防止结果重复。但这是多余的。单个查询的所有CTE都可以看到表的相同快照。返回ON CONFLICT (name, url, email) DO NOTHING的集合INNER JOIN与同一列上的之后返回的集合互斥。
不幸的是,这也为比赛条件打开了一个很小的窗口。如果…
你可能只是INSERT .. ON CONFLICT DO NOTHING,紧接着是SELECT对所有行的单独查询-在同一个事务内即可解决此问题。这反过来又打开另一个小窗户的竞争条件,如果并发事务可以承诺之间写入表INSERT和SELECT(在默认的READ COMMITTED隔离级别)。可以通过REPEATABLE READ事务隔离(或更严格)来避免。或者在整个表上使用(可能很昂贵,甚至是不可接受的)写锁。你可以获得所需的任何行为,但可能需要付出一定的代价。
在我的根项目中,我有两个子项目具有这种包结构。 在项目1中,我有一个用大规定义的类,就像这样 问题是,如果我运行该测试,它也会分析项目2中的所有内容。我如何排除包com.app.api?
问题内容: 我用来捆绑一个应用程序。 我所有的组件在顶部都有一个。这导致将源包括在我的捆绑包中。但我想排除它。 我怎么做?这是正确的做法吗? 问题答案: @NickTomlin给出了此答案,但随后将其删除。 您可以使用: 使用api的示例: 这是一个可行的选择。 需要另一个脚本以兼容方式提供模块。您可以生成这样的脚本: 在HTML中: dest.js是您的代码,但没有反应。react.js只是re
在使用maven apache felix插件构建捆绑jar时,如何排除一些META-INF文件? 这是我的felix配置 我正在引入所有传递依赖项并嵌入它们,因为我想创建一个可以添加到类路径的jar。 当我尝试运行我的jar时,尽管我遇到了异常 在SO上找到一篇帖子后,我手动删除了一些似乎来自bouncy文件的META-INF/file。然后我重新创建了jar文件,它成功了。有没有一种方法可以使
我的需求: 先从列表=>详情页 如果在详情页点击的返回按钮,则读取之前缓存的历史数据 (在详情页刷新后再点击返回,也符合条件) 此时的返回包括: 浏览器的返回按钮 页面中的按钮(调用router.back()/go(-1)等路由方法) 要如何全局判断用户进行了返回操作呢?
问题内容: 我在node.js中编写一个函数来查询PostgreSQL表。 如果该行存在,我想从该行返回id列。 如果不存在,我想将其插入并返回ID()。 我一直在尝试和语句的变体,但似乎无法使其正常工作。 问题答案: 我建议在数据库端进行检查,然后将ID返回给nodejs。 例子: 而不是在Node.js端(在此示例中,我使用的是node-postgres):
问题内容: 我们有一个与已删除的某些需求相关的软件包,但我们不想删除该代码,因为将来可能会再次需要它。因此,在我们现有的ant构建中,我们只是将该包排除在了jar中之外。这些类由于我们还删除了它们的依赖关系而无法编译,因此它们不能包含在构建中。 我正在尝试模仿Gradle中的功能,如下所示: 即使使用上面的exclude调用(并且我也尝试过不带方括号的尝试),gradle仍在尝试编译类,这会导致编