programing

PostgreSQL: 고유 위반: 7 오류: 중복 키 값이 고유 제약 조건 "users_pkey"를 위반함

sourcejob 2023. 7. 23. 14:14
반응형

PostgreSQL: 고유 위반: 7 오류: 중복 키 값이 고유 제약 조건 "users_pkey"를 위반함

저는 제 라라벨 앱에서 psql을 사용하고 있습니다.사용자를 생성하려고 하는데 이 오류가 계속 발생합니다.

고유 위반: 7 오류: 중복 키 값이 고유 제약 조건 "users_pkey"를 위반합니다.


사용자를 저장하기 위해 수행한 작업

$user = User::where('account_id','=',$id)->first();
$user->email = $account->email_address;
$user->fb_email = '';
$user->tw_email = '';
$user->fb_access_token = '';
$user->fb_profile_id = '';
$user->fb_page_id = '';
$user->fb_username = '';
$user->save();

사용자 테이블을 만든 방법은 다음과 같습니다.

CREATE TABLE "users" (
    "id" serial NOT NULL ,
    "account_id" varchar(255) NOT NULL ,
    "email" varchar(255) NOT NULL ,
    "fb_email" varchar(255) NOT NULL ,
    "tw_email" varchar(255) NOT NULL ,
    "created_at" timestamp(0) without time zone,
    "updated_at" timestamp(0) without time zone,
    "fb_access_token" varchar(255) NOT NULL ,
    "fb_profile_id" varchar(255) NOT NULL ,
    "fb_page_id" varchar(255) NOT NULL ,
    "fb_username" varchar(255) NOT NULL ,
    PRIMARY KEY ("id")

);

내가 지금 하고 있는 일을 했습니까?not할 것 같습니까?

내가 지금 가지고 있는 것은 내가 내 앱을 후크할 때 작동합니다.MySQL.

어떤 힌트나 제안도 저에게는 큰 의미가 있을 것입니다.


스크린샷

enter image description here

Postgres는 자동 증분을 MySQL과 조금 다르게 처리합니다.Postgres에서 다음을 생성할 때serial필드에서 사용할 ID를 추적하는 시퀀스 필드도 만듭니다.이 시퀀스 필드는 1 값으로 시작합니다.

테이블에 새 레코드를 삽입할 때 다음을 지정하지 않은 경우id필드에서 시퀀스 값을 사용한 다음 시퀀스를 증분합니다.그러나 지정한 경우id필드를 선택하면 시퀀스가 사용되지 않으며 업데이트되지도 않습니다.

Postgres로 이동할 때 일부 기존 사용자와 해당 사용자의 기존 ID를 시드하거나 가져온 것으로 가정합니다.ID로 이러한 사용자 레코드를 만들 때 시퀀스가 사용되지 않았기 때문에 업데이트되지 않았습니다.

예를 들어, 10명의 사용자를 가져온 경우 ID가 1-10인 사용자가 있지만 시퀀스는 여전히 1입니다.ID를 지정하지 않고 새 사용자를 생성하려고 하면 시퀀스(1)에서 값을 가져오며, ID가 1인 사용자가 이미 있기 때문에 고유한 위반이 발생합니다.

이 문제를 해결하려면 다음을 설정해야 합니다.users_id_seq시퀀스 값을 기존 사용자의 MAX(id)로 지정합니다.시퀀스 재설정에 대한 자세한 내용은 이 질문/답변을 참조할 수 있지만, 다음과 같은 방법을 시도할 수도 있습니다(테스트되지 않음).

SELECT setval(pg_get_serial_sequence('users', 'id'), coalesce(max(id)+1, 1), false) FROM users;

참고로, 값이 자동 증분 필드에 수동으로 삽입될 때 MySQL은 자동 증분 시퀀스를 가장 큰 열 값으로 자동 업데이트하므로 MySQL에서는 이 문제가 발생하지 않습니다.

다음 코드는 OP가 사용하는 라라벨에서 이를 수행하는 방법을 제공합니다.

// Get all the tables from your database
$tables = \DB::select('SELECT table_name FROM information_schema.tables WHERE table_schema = \'public\' ORDER BY table_name;'); 

// Set the tables in the database you would like to ignore
$ignores = array('admin_setting', 'model_has_permissions', 'model_has_roles', 'password_resets', 'role_has_permissions', 'sessions'); 

//loop through the tables
foreach ($tables as $table) { 

   // if the table is not to be ignored then:
   if (!in_array($table->table_name, $ignores)) { 

       //Get the max id from that table and add 1 to it
       $seq = \DB::table($table->table_name)->max('id') + 1; 

       // alter the sequence to now RESTART WITH the new sequence index from above        
       \DB::select('ALTER SEQUENCE ' . $table->table_name . '_id_seq RESTART WITH ' . $seq); 

    }

}

참고 - ALTER SEQUENCE를 사용하면 "동시 트랜잭션 차단"됩니다.원하지 않는 경우 위에 제공된 대체 솔루션의 SQL 문을 사용하는 것이 좋습니다.

일반적으로 테이블을 내보내고 다른 데이터베이스로 가져올 때 이 오류가 발생합니다.

위의 방법들은 작동하지만 안타깝게도 제 시스템에서는 작동하지 않습니다. 제가 사용하는 시스템은 label과 postgres입니다.

나는 테이블을 비우는 것으로 나의 문제를 해결했습니다.

TRUNCATE TABLE table_name;

Postgre에서 모든 테이블 시퀀스를 편집할 수도 있습니다.DB 관리 소프트웨어가 포함된 SQL.예를 들어 pgAdmin4를 사용합니다.해당 테이블에 대한 최신 기본 키를 확인한 후 DB -> Schemas -> 1.3 Sequences -> table -> Properties -> Definition and Edit 필드 Current 값으로 이동합니다.

언급URL : https://stackoverflow.com/questions/37970743/postgresql-unique-violation-7-error-duplicate-key-value-violates-unique-const

반응형