PG::ConnectionBad: PQsocket() 无法获取套接字描述符:删除记录时回滚

PG::ConnectionBad: PQsocket() can't get socket descriptor: ROLLBACK on deleting record

运行:

Price.find(208999).delete

rails 控制台 中,导致错误消息:

SQL (0.0ms)  DELETE FROM "prices" WHERE "prices"."id" =   [["id", 208999]]
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQsocket() can't get 
socket descriptor: DELETE FROM "prices" WHERE "prices"."id" = '

相同命令的后续重试结果:

SQL (4.0ms)  DELETE FROM "prices" WHERE "prices"."id" =   [["id", 208999]]
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQconsumeInput() server 
closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
: DELETE FROM "prices" WHERE "prices"."id" = 

此时我无法 运行 任何查询命令而不 运行 解决这个问题。在我 运行 删除之前,我可以在另一个 table 上删除另一个 SQL。

我已经尝试了与此错误相关的堆栈溢出的所有其他链接:

我没有设置任何 spec/rspec rake 任务,但是我已经尝试 rails tmp:clear 其中指出,"# 从...清除缓存和套接字文件"

我已经检查过这条记录是否与另一条记录有任何关联 table,但是我的搜索没有返回任何结果。

经过几个小时的搜索...

问题是在我的 price.rb 模型文件中,我声明了以下关系:

class Price < ApplicationRecord
    belongs_to :card

    has_and_belongs_to_many :collections

    has_many :types

    class << self # Class methods
    end
end

我删除了 price.types 关联记录,但是我没有反方向删除 card.prices 关联记录。

所以命令我 运行 其中:

price = Price.find(208999)

card = price.card

#delete price_card association record
card.prices.delete(price)

#now i'll be able to delete the price record
price.delete

确实需要一个更好的错误消息,因为我一直在修改我的 database.yml 文件并重置我的套接字,因为这就是错误消息让你相信的。

希望这会在其他人开始摆弄数据库配置之前对他们有所帮助。


编辑 2

刚刚又遇到这个问题,我更新到最新版本的 PostgreSQL,它是 12.4,因为我读到 dba stackexchange answer 这是在 PostgreSQL 11 中发出 DELETE sql 命令时的常见问题我在做什么 运行。

并没有解决问题。

下载并仔细查看 pgAdmin4 生成的日志文件后,我发现了对关系键的引用,因此我创建了一个小脚本来遍历所有记录,并将任何外键值设置为 nil 所以在删除时,它没有抛出任何令人讨厌的错误。

Product.all.each do |product|
  product.update(cardset_id:nil,language_id:nil)
  product.delete
end

编辑 3

所以我终于弄清楚了我的 PostgreSQL 数据库崩溃的真正原因..

我有一个名为 Cards 的 table,它有一个 slug 字段,其中设置了 unique: true 选项。

在我的 Card 模型中,我有一个函数

extend FriendlyId
friendly_id (:slug_id), use: :slugged

def slug_id
    [
        [:name, :cardset_id],
    ]
end

通过名称和 cardset_id 的混合创建了一个 slug,但是如果我想要同一记录的不同副本,出于某种原因创建相同的 slug id。

当 PostgreSQL 去获取这条记录时,它中断了,因为数据没有意义并且它一开始就不应该存在。

所以我的 slug 函数有问题,没有按预期运行。

在删除每条记录之前,我只是将 slug 设置为 运行dom 值,然后将其删除。