重複したデータエクスプローラーキーが再構築をブロックしています

みなさん、こんにちは。

滅多に助けを求めないのですが、この問題の解決方法がわからずに困っています。

サイトを再構築したところ、以下のエラーが発生しました。

discourse-data-explorer は既に最新互換バージョンです

I, [2020-08-28T17:53:57.578920 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
2020-08-28 17:54:07.380 UTC [3060] discourse@discourse ERROR:  duplicate key value violates unique constraint "data_explorer_queries_pkey"
2020-08-28 17:54:07.380 UTC [3060] discourse@discourse DETAIL:  Key (id)=(-7) already exists.
2020-08-28 17:54:07.380 UTC [3060] discourse@discourse STATEMENT:  INSERT INTO data_explorer_queries(id, name, description, sql, user_id, last_run_at, hidden, created_at, updated_at)
        SELECT
          (replace(key, 'q:',''))::integer,
          value::json->>'name',
          value::json->>'description',
          value::json->>'sql',
          CASE WHEN (value::json->'created_by')::text = 'null' THEN
            null
          WHEN (value::json->'created_by')::text = '""' THEN
            null
          WHEN (value::jsonb ? 'created_by') THEN
            (value::json->>'created_by')::integer
          ELSE
            null
          END,
          CASE WHEN (value::json->'last_run_at')::text = 'null' THEN
            null
          WHEN (value::json->'last_run_at')::text = '""' THEN
            null
          ELSE
            (value::json->'last_run_at')::text::timestamptz
          END,
          CASE WHEN (value::json->'hidden')::text = 'null' THEN
            false
          WHEN (value::jsonb ? 'hidden') THEN
            (value::json->'hidden')::text::boolean
          ELSE
            false
          END,
          '2020-08-28 17:54:07.368132',
          '2020-08-28 17:54:07.368132'
        FROM plugin_store_rows
        WHERE plugin_name = 'discourse-data-explorer' AND type_name = 'JSON' AND (replace(key, 'q:',''))::integer < 0

rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

ERROR:  duplicate key value violates unique constraint "data_explorer_queries_pkey"

重要な部分は ERROR: duplicate key value violates unique constraint "data_explorer_queries_pkey" です。

Rails コンソールで ID が -7 のクエリを見つけましたが、どうやら組み込みのクエリの一つのようです。

[5] pry(main)> DataExplorer::Query.find(-7)
=> #<DataExplorer::Query:0x000055e44bbb4038
 @created_by="-1",
 @description="based on post score calculated using reply count, likes, incoming links, bookmarks, time spent and read count.",
 @group_ids=[],
 @hidden=nil,
 @id=-7,
 @last_run_at="2020-01-03T18:06:31.966+00:00",
 @name="Top 50 Quality Users",
 @sql=
  "SELECT sum(p.score) / count(p) AS \"average score per post\",\n    count(p.id) AS post_count,\n    p.user_id\nFROM posts p\nJOIN users u ON u.id = p.user_id\nWHERE p.created_at >= CURRENT_DATE - INTERVAL '6 month'\nAND NOT u.admin\nAND u.active\nGROUP BY user_id,\n    u.views\nHAVING count(p.id) > 50\nORDER BY sum(p.score) / count(p) DESC\nLIMIT 50">

PL/SQL プロンプトにもアクセスできましたが、確信が持てません。新しいクエリを挿入できるようにするために、組み込みクエリを削除すべきでしょうか?

「いいね!」 2

psql に接続し、以下を実行してください:

     SELECT
          (replace(key, 'q:',''))::integer,
          value::json->>'name',
          value::json->>'description',
          value::json->>'sql',
          CASE WHEN (value::json->'created_by')::text = 'null' THEN
            null
          WHEN (value::json->'created_by')::text = '""' THEN
            null
          WHEN (value::jsonb ? 'created_by') THEN
            (value::json->>'created_by')::integer
          ELSE
            null
          END,
          CASE WHEN (value::json->'last_run_at')::text = 'null' THEN
            null
          WHEN (value::json->'last_run_at')::text = '""' THEN
            null
          ELSE
            (value::json->'last_run_at')::text::timestamptz
          END,
          CASE WHEN (value::json->'hidden')::text = 'null' THEN
            false
          WHEN (value::jsonb ? 'hidden') THEN
            (value::json->'hidden')::text::boolean
          ELSE
            false
          END,
          '2020-08-28 17:54:07.368132',
          '2020-08-28 17:54:07.368132'
        FROM plugin_store_rows
        WHERE plugin_name = 'discourse-data-explorer' AND type_name = 'JSON' AND (replace(key, 'q:',''))::integer < 0;
「いいね!」 4

2 行が返ってきましたが、見た目には同じです。「Top 50 Quality Users」

奇妙なことに、以下のように実行すると:

[3] pry(main)> PluginStoreRow.where(plugin_name: 'discourse-data-explorer', key: "q:-7")
=> [#<PluginStoreRow:0x000055e280408bf8
  id: 1286,
  plugin_name: "discourse-data-explorer",
  key: "q:-7",
  type_name: "JSON",
  value:
   "{\"id\":-7,\"name\":\"Top 50 Quality Users\",\"description\":\"based on post score calculated using reply count, likes, incoming links, bookmarks, time spent and read count.\",\"sql\":\"SELECT sum(p.score) / count(p) AS \\\"average score per post\\\",\\n    count(p.id) AS post_count,\\n    p.user_id\\nFROM posts p\\nJOIN users u ON u.id = p.user_id\\nWHERE p.created_at \\u003e= CURRENT_DATE - INTERVAL '6 month'\\nAND NOT u.admin\\nAND u.active\\nGROUP BY user_id,\\n    u.views\\nHAVING count(p.id)
 \\u003e 50\\nORDER BY sum(p.score) / count(p) DESC\\nLIMIT 50\\n\",\"created_by\":\"-1\",\"created_at\":null,\"group_ids\":[],\"last_run_at\":\"2020-01-03T18:06:31.966+00:00\"}">
]

id が -7 の行が 1 つだけあるように見えますが、これは正しいでしょうか?

「いいね!」 2

OK、これを以下のように簡略化しても問題ありませんか:

select * from plugin_store_rows WHERE plugin_name = 'discourse-data-explorer' AND type_name = 'JSON' AND (replace(key, 'q:',''))::integer < 0;

これにより、‘id’ を除いて 2 つの同一行が返されます。

勇気を出して 1 つ削除すべきでしょう!

追伸:完了しました。新しいレコードを削除しました。再構築中です

(DELETE from plugin_store_rows WHERE id = $$$重複レコードの ID$$$; を使用しました)

マイグレーションが正常に動作しました!

@Falco さん、押し続けていただきありがとうございます

「いいね!」 8

それが、今後このようなケースを防ぐために専用テーブルに移行する全理由です。残念ですが、あなたには先に手に入ってしまったようですね😜

「いいね!」 6

詳しい修正ありがとうございます。私も同じ問題(重複する id が 2 つある)に遭遇しましたが、その方法で解決しました。

「いいね!」 2

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.