相关疑难解决方法(0)

处理PostgreSQL中的竞争条件

我有几个工作者,每个工作者都拥有自己与PostgreSQL的连接.工人们操纵着不同的桌子.

工作人员处理来自系统外部的并行请求.正在访问的表之一是用户表.当一些信息出现时,我首先需要确保表中的用户有一条记录.如果没有记录,我希望首先创建一个.

我正在使用以下成语:

if [user does not exist] then [create user]
Run Code Online (Sandbox Code Playgroud)

代码[user does not exist]是:

SELECT id FROM myschema.users WHERE userId='xyz'
Run Code Online (Sandbox Code Playgroud)

我测试是否返回任何行.

(简化)代码[create user]是:

INSERT INTO myschema.users VALUES ('xyz')
Run Code Online (Sandbox Code Playgroud)

当我的系统处理有关同一用户的不同信息的并行流时,我经常会收到PostgreSQL错误:

Key (id)=(xyz) already exists
Run Code Online (Sandbox Code Playgroud)

之所以发生这种情况是因为该SELECT命令不返回任何行,然后另一个工作程序创建用户,任何我的工作程序都尝试执行相同操作,从而导致示例性并发错

根据PostgreSQL文档,默认情况下,每当我隐式启动一个事务时,只要我不提交它,表就会被锁定.我没有使用自动提交,我只在块中提交事务,例如在整个if-else块之后.

实际上,我可以if-else直接将这些东西放入SQL中,但它并不能解决我的锁定问题.我假设"赢家全部使用"范例将起作用,并且设法执行SELECT命令的第一个工作人员将拥有锁,直到它调用COMMIT.

我在SO上已经阅读了很多不同的主题,但我仍然不确定什么是正确的解决方案.我应该使用显式锁定表,因为隐式锁定不起作用?我怎样才能确保只有一个工人拥有一张桌子?

sql postgresql concurrency multithreading locking

11
推荐指数
2
解决办法
4663
查看次数

如果一行不存在,则插入else不会在postgres中插入

我需要检查是否存在行.如果它不存在,则应插入.

这是在postgres,我试图通过shell脚本插入行.当我运行脚本时,它不显示错误,但即使没有匹配的行,它也不会插入到表中.

sql postgresql

9
推荐指数
1
解决办法
3万
查看次数

如何仅在不存在的情况下创建记录,避免重复并且不会引发任何错误?

众所周知,Model.find_or_create_by(X)实际上:

  1. 由X选择
  2. 如果找不到 - >由X创建
  3. 返回记录(找到或创建)

在步骤1和2之间可能存在争用条件.为了避免数据库中的X重复,应该在X的字段集上使用唯一索引.但是如果应用唯一索引,那么竞争事务之一将失败异常(尝试创建X的副本时).

如何实现"安全版本",#find_or_create_by它永远不会引发任何异常并始终按预期工作?

postgresql transactions ruby-on-rails upsert rails-activerecord

8
推荐指数
1
解决办法
5834
查看次数

批量更新Redshift中的现有行

这似乎应该很容易,但事实并非如此.我正在将查询从MySQL迁移到表格的Redshift:

INSERT INTO table
(...)
VALUES
(...)
ON DUPLICATE KEY UPDATE
  value = MIN(value, VALUES(value))
Run Code Online (Sandbox Code Playgroud)

对于主键,我们正在插入表中尚未插入的主键.对于已在表中的主键,我们根据取决于行中现有值和新值的条件更新行的值.

http://docs.aws.amazon.com/redshift/latest/dg/merge-replacing-existing-rows.html不起作用,因为filter_expression在我的情况下取决于表中的当前条目.我正在创建一个临时表,插入一个COPY语句,并试图找出合并登台和真实表的最佳方法.

sql postgresql amazon-redshift

8
推荐指数
1
解决办法
1万
查看次数

使用SQLAlchemy批量上传

我正在使用SQLAlchemy 1.1.0b将大量数据批量上传到PostgreSQL中,并且遇到了重复的关键错误。

from sqlalchemy import *
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.automap import automap_base

import pg

engine = create_engine("postgresql+pygresql://" + uname + ":" + passw + "@" + url)

# reflectively load the database.
metadata = MetaData()
metadata.reflect(bind=engine)
session = sessionmaker(autocommit=True, autoflush=True)
session.configure(bind=engine)
session = session()
base = automap_base(metadata=metadata)
base.prepare(engine, reflect=True)

table_name = "arbitrary_table_name" # this will always be arbitrary
mapped_table = getattr(base.classses, table_name)
# col and col2 exist in the table.
chunks = [[{"col":"val"},{"col2":"val2"}],[{"col":"val"},{"col2":"val3"}]]

for chunk in chunks:
    session.bulk_insert_mappings(mapped_table, …
Run Code Online (Sandbox Code Playgroud)

python postgresql sqlalchemy upsert

7
推荐指数
1
解决办法
6224
查看次数

在postgres上使用什么代替“ INSERT ... ON CONFLICT DO NOTHING”

我有以下查询,与postgres 9.5一起使用:

INSERT INTO knowledge_state 
(SELECT learnerid learner_id, lo_id FROM qb_lo_tag WHERE qb_id = NEW.qb_id)
ON CONFLICT DO NOTHING ;
Run Code Online (Sandbox Code Playgroud)

不幸的是,我不能在某些服务器上使用postgres 9.5,我需要将其转换为9.5之前的友好查询。我建立了以下查询,但对我来说似乎复杂得多,我认为可能有更简单的方法。

FOR rows IN SELECT lo_id FROM knowledge_state 
WHERE learner_id = learnerid 
AND lo_id IN (SELECT lo_id FROM qb_lo_tags WHERE qb_id = New.qb_id) LOOP

  INSERT INTO knowledge_state (lo_id, learner_id) SELECT rows.lo_id, learnerid 
WHERE NOT EXISTS (SELECT * FROM knowledge_state WHERE lo_id = rows.lo_id AND learner_id = learnerid);

END LOOP;
Run Code Online (Sandbox Code Playgroud)

我很想听听有关如何简化此查询的想法。

postgresql

6
推荐指数
1
解决办法
9447
查看次数

如何制作ActiveRecord ThreadSafe

如何使用postgresql在rails 4中创建以下控制器线程安全:

def controller_action
  if Model.exists(column_name:"some_value")
  else
    @model=Model.new(column_name:"some_value")
    @model.save
  end
end
Run Code Online (Sandbox Code Playgroud)

我正在运行puma,所以我担心的是,如果两个线程同时运行此控制器,并且不存在具有指定值column_name的行,则将创建两个记录,而我只想要1.

postgresql ruby-on-rails thread-safety ruby-on-rails-4 rails-activerecord

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

插入多行时重复项会发生什么?

我正在运行一个python脚本,将大量数据插入到Postgres数据库中,我使用单个查询来执行多行插入:

INSERT INTO table (col1,col2) VALUES ('v1','v2'),('v3','v4') ... etc
Run Code Online (Sandbox Code Playgroud)

我想知道如果它碰到插入的重复键会发生什么.它会停止整个查询并抛出异常吗?或者它只是忽略该特定行的插入并继续前进?

sql postgresql exception upsert duplicates

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

Ruby不释放内存

我有或多或少看起来像这样的Ruby代码

offset = 0
index = 1

User.establish_connection(..) # db1
class Member < ActiveRecord::Base
  self.table_name = 'users'
end 

Member.establish_connection(..) #db2

while true
  users = User.limit(10000).offset(offset).as_json ## for a Database 1
  offset = limit * index
  index += 1
  users.each do |u|
    member =  Member.find_by(name: u[:name])
    if member.nil?
      Member.create(u)
    elsif member.updated_at < u[:updated_at]   
      member.update_attributes(u)   
    end
  end 
  break if break_condition
end
Run Code Online (Sandbox Code Playgroud)

我所看到的是RSS内存(htop)不断增长,并且一度达到10GB.我不确定为什么会发生这种情况但是Ruby似乎永远不会将内存释放回操作系统.

我知道有很多问题都与此相符.我甚至尝试通过代码更改看起来像这样(具体是最后3行).ie GC.start手动运行结果仍然相同.

while true

....
...
...
users = nil
GC.start
break if break_condition
end
Run Code Online (Sandbox Code Playgroud)

关于Ruby版本测试这2.2.22.3.0 …

ruby memory ruby-2.3

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

在"ON"或附近发布postgres语法错误

我创建了这个表:

CREATE TABLE IF NOT EXISTS config_activity_log
(
  id                      serial primary key,
  activity_name           varchar(100) NOT NULL,
  last_config_version     varchar(50) NOT NULL,
  activity_status         varchar(100) NOT NULL DEFAULT 'Awaiting for cofman',
  cofman_last_update      bigint NOT NULL DEFAULT -1,
  is_error                boolean DEFAULT FALSE,
  activity_timestamp      timestamp DEFAULT current_timestamp
);
Run Code Online (Sandbox Code Playgroud)

我尝试运行这个postgres脚本:

INSERT INTO config_activity_log
    (activity_name, last_config_version, activity_status)
VALUES
    ('test awating deployment','5837-2016-08-24_09-12-22', 'Awaiting for deployment')
ON CONFLICT (activity_name)
DO UPDATE SET
    activity_status = EXCLUDED.activity_status
Run Code Online (Sandbox Code Playgroud)

为什么我会收到此语法错误?

psql:upsert_test_log.sql:7: ERROR:  syntax error at or near "ON"
LINE 5: ON CONFLICT (activity_name)
Run Code Online (Sandbox Code Playgroud)

sql postgresql upsert

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