我有几个工作者,每个工作者都拥有自己与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上已经阅读了很多不同的主题,但我仍然不确定什么是正确的解决方案.我应该使用显式锁定表,因为隐式锁定不起作用?我怎样才能确保只有一个工人拥有一张桌子?
我需要检查是否存在行.如果它不存在,则应插入.
这是在postgres,我试图通过shell脚本插入行.当我运行脚本时,它不显示错误,但即使没有匹配的行,它也不会插入到表中.
众所周知,Model.find_or_create_by(X)实际上:
在步骤1和2之间可能存在争用条件.为了避免数据库中的X重复,应该在X的字段集上使用唯一索引.但是如果应用唯一索引,那么竞争事务之一将失败异常(尝试创建X的副本时).
如何实现"安全版本",#find_or_create_by它永远不会引发任何异常并始终按预期工作?
postgresql transactions ruby-on-rails upsert rails-activerecord
这似乎应该很容易,但事实并非如此.我正在将查询从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语句,并试图找出合并登台和真实表的最佳方法.
我正在使用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) 我有以下查询,与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在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
我正在运行一个python脚本,将大量数据插入到Postgres数据库中,我使用单个查询来执行多行插入:
INSERT INTO table (col1,col2) VALUES ('v1','v2'),('v3','v4') ... etc
Run Code Online (Sandbox Code Playgroud)
我想知道如果它碰到插入的重复键会发生什么.它会停止整个查询并抛出异常吗?或者它只是忽略该特定行的插入并继续前进?
我有或多或少看起来像这样的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.2和2.3.0 …
我创建了这个表:
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) postgresql ×9
sql ×5
upsert ×4
concurrency ×1
duplicates ×1
exception ×1
locking ×1
memory ×1
python ×1
ruby ×1
ruby-2.3 ×1
sqlalchemy ×1
transactions ×1