Seedを実行した後にシーケンスを更新する方法(duplicate key valueエラー)
Seedでidを指定してINSERTしたあとにORMでINSERTを行うとduplicate key valueのエラーが出ることがあります。
[参考記事] PostgreSQLのERROR: duplicate key value
ERROR: duplicate key value violates unique constraint "hoge_pkey" DETAIL: Key (id)=(10) already exists.
PostgreSQLでは、プライマリキーの自動採番(AUTO INCREMENT)はシーケンス(sequence)によって管理されています。
[参考記事] 自動採番をするシーケンス(sequence)とは
idを指定してINSERTした場合は、シーケンスは更新されません。
またプライマリキーとシーケンス(sequence)は自動的に同期されないため、次にidを指定せずINSERTを行うとプライマリキーの重複が起こり上記のエラーが発生します。
マスターデータなどプライマリキーのidを指定してINSERTするときなどに発生します。
プライマリキーとシーケンス(sequence)を同期させるには、次のようなSQLを実行する必要があります。
[参考記事] プライマリキーとシーケンスを同期させるには
SELECT SETVAL ('【シーケンス名】', (SELECT MAX(【プライマリキー名】) FROM 【テーブル名】)); 例 SELECT SETVAL ('users_id_seq', (SELECT MAX(id) FROM users));
SeedでINSERTしたあとにシーケンスを同期させるSQLを実行するには次のようにします。
[参考記事] SQLクエリーを直接実行する方法
<?php
declare(strict_types=1);
use Cake\Datasource\ConnectionManager;
use Migrations\AbstractSeed;
/**
* Users seed.
*/
class UsersSeed extends AbstractSeed
{
/**
* Run Method.
*
* @return void
*/
public function run()
{
$data = [
[
'id' => 1,
'email' => 'test@example.com',
'name' => 'テスト太郎',
],
[
'id' => 2,
'email' => 'hoge@example.com',
'name' => 'ほげほげ',
],
];
$table = $this->table('users');
$table->insert($data)->save();
// Postgresではシーケンスを更新する
$connection = ConnectionManager::get('default');
if (strpos(strtolower($connection->config()['driver']), 'postgres') !== false) {
$connection->execute("SELECT SETVAL ('users_id_seq', (SELECT MAX(id) FROM users));")->fetchAll('assoc');
}
}
}
他のRDBMSでも使用する可能性がなければ下記のコードのみで問題はありません。
$connection = ConnectionManager::get('default');
$connection->execute("SELECT SETVAL ('users_id_seq', (SELECT MAX(id) FROM users));")->fetchAll('assoc');
MySQLなどにはシーケンスはないため、下記のコードでPostgresSQLのみで実行するように制限をしています。
if (strpos(strtolower($connection->config()['driver']), 'postgres') !== false) { }
関連記事
- カラム一覧を取得する方法
- テンプレート(template)側でログイン情報を取得する方法
- フォームの必須エラーメッセージをHTML5標準にする方法、カスタマイズする方法
- 標準のHelperを拡張してカスタマイズする方法
- 国際化i18n(多言語化)
- URLをハイフン区切りからアンダーバー区切りやキャメルケースにする方法
- CakePHP4系の入手方法・インストール方法
- Composerコマンドでウクライナへのメッセージが表示されたことがあります
- Composerをインストールする方法と使い方
- コーディング規約のチェックを行う・整形する標準ツール(PHP CodeSniffer)の使い方
- Seedの実行順(外部キー制約などを先に実行させる方法) Foreign key violation
- SQLクエリー(SQL文)を直接実行する方法
- PostgreSQLでERROR: duplicate key value violates unique constraint "hoge_pkey" DETAIL: Key (id)=(10) already exists.と出る場合
- PostgreSQLで自動採番をするシーケンス(sequence)とは【AUTO INCREMENT】
- Apacheで所有権や書き込み権限があるにも関わらずPermissions deniedが出る場合
- PostgreSQL
- CakePHP3
- CakePHPでカラムを比較してSELECTする方法
- PostgreSQLのインストール
- 1つのフィールドにバリデーションエラーを1つだけ表示させる方法
- EC-CUBEのサーバ移行の方法
- Zend_DBのSELECTメソッドのまとめ
- Zend Frameworkのデータベース接続
- EC-CUBEのバックアップ機能とリストア
- CakePHPのバージョンごとのシステム要件
- PostgreSQLでSCRAM authentication requires libpq version 10 or aboveと出るとき
- Zend_DBの基本
- CakePHP3系の入手方法・インストール方法
- PostgreSQLのインストール
- AuthコンポーネントのパスワードをCakePHPを使用せずハッシュ化する方法(パスワードの生成ルール)
- 複数のデータベースを切り替える方法(別データベースを使用する)
- CakePHPのDB接続情報設定
スポンサーリンク