복붙노트

[SQL] 기본 키 위반 오류 후 거래를 계속

SQL

기본 키 위반 오류 후 거래를 계속

나는 로그 파일에서 데이터베이스로 기록의 대량 삽입을하고있는 중이 야. 때때로 (~ 모든 천 중 1 행) 행 중 하나는 기본 키를 위반하고 트랜잭션이 실패합니다. 현재, 사용자가 수동으로 고장의 원인이 된 파일을 통해 이동하고 다시 수입하기 전에 문제가되는 행을 제거 할 수있다. 이러한 파일의 수백이 불가능하다 가져올 수 있다는 것을 감안할 때.

내 질문 : 어떻게 이미 존재하는지 각 행하기 전에 SELECT 문을 할 필요없이, 기본 키 제약 조건을 위반하는 것입니다 레코드의 삽입을 건너 뛸 수 있습니다?

참고 : 나는 매우 비슷한 질문 # 1054695 알고있다, 그러나 SQL 서버의 특정 응답 것으로 보인다 나는 (파이썬 / psycopg2를 통해 수입) PostgreSQL을 사용하고 있습니다.

해결법

  1. ==============================

    1.또한 트랜잭션 세이브 포인트를 사용할 수 있습니다.

    또한 트랜잭션 세이브 포인트를 사용할 수 있습니다.

    Pythonish 의사는 애플리케이션 측으로부터 도시이다 :

    database.execute("BEGIN")
    foreach data_row in input_data_dictionary:
        database.execute("SAVEPOINT bulk_savepoint")
        try:
            database.execute("INSERT", table, data_row)
        except:
            database.execute("ROLLBACK TO SAVEPOINT bulk_savepoint")
            log_error(data_row)
            error_count = error_count + 1
        else:
            database.execute("RELEASE SAVEPOINT bulk_savepoint")
    
    if error_count > error_threshold:
        database.execute("ROLLBACK")
    else:
        database.execute("COMMIT")
    

    편집 : 여기 (SQL 문 접두사 ">") 문서의 예에 약간의 변화에 ​​따라 psql의의 행동이의 실제 예입니다 :

    > CREATE TABLE table1 (test_field INTEGER NOT NULL PRIMARY KEY);
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "table1_pkey" for table "table1"
    CREATE TABLE
    
    > BEGIN;
    BEGIN
    > INSERT INTO table1 VALUES (1);
    INSERT 0 1
    > SAVEPOINT my_savepoint;
    SAVEPOINT
    > INSERT INTO table1 VALUES (1);
    ERROR:  duplicate key value violates unique constraint "table1_pkey"
    > ROLLBACK TO SAVEPOINT my_savepoint;
    ROLLBACK
    > INSERT INTO table1 VALUES (3);
    INSERT 0 1
    > COMMIT;
    COMMIT
    > SELECT * FROM table1;  
     test_field 
    ------------
              1
              3
    (2 rows)
    

    값 3이 여전히 동일한 트랜잭션 내부 오류 후 삽입합니다!

    SAVEPOINT에 대한 문서는 http://www.postgresql.org/docs/8.4/static/sql-savepoint.html이다.

  2. ==============================

    2.나는 당신의 고유의 위반에 예외를 잡기 위해 저장 프로 시저를 사용합니다. 예:

    나는 당신의 고유의 위반에 예외를 잡기 위해 저장 프로 시저를 사용합니다. 예:

    CREATE OR REPLACE FUNCTION my_insert(i_foo text, i_bar text)
      RETURNS boolean LANGUAGE plpgsql AS
    $BODY$
    begin   
        insert into foo(x, y) values(i_foo, i_bar);
        exception
            when unique_violation THEN -- nothing
    
        return true;
    end;
    $BODY$;
    
    SELECT my_insert('value 1','another value');
    
  3. ==============================

    3.당신은 예외를 (CR 커서입니다) 제기 코드 앞에 점을 저장에 거래 롤백 또는 롤백을 수행 할 수 있습니다 :

    당신은 예외를 (CR 커서입니다) 제기 코드 앞에 점을 저장에 거래 롤백 또는 롤백을 수행 할 수 있습니다 :

    name = uuid.uuid1().hex
    cr.execute('SAVEPOINT "%s"' % name)
    try:
        # your failing query goes here
    except Exception:
        cr.execute('ROLLBACK TO SAVEPOINT "%s"' % name)
        # your alternative code goes here 
    else:
        cr.execute('RELEASE SAVEPOINT "%s"' % name)
    

    이 코드는, 그렇지 않으면 당신이 오류 메시지가 나타날 것 트랜잭션을 실행이 가정합니다.

    장고 PostgreSQL의 백엔드 psycopg에서 직접 커서를 만듭니다. 어쩌면 미래에 그들은 odoo의 커서 유사한 장고 커서에 프록시 클래스를 확인합니다. 그들은 다음 코드 (자기가 커서입니다)로 커서를 확장 :

    @contextmanager
    @check
    def savepoint(self):
        """context manager entering in a new savepoint"""
        name = uuid.uuid1().hex
        self.execute('SAVEPOINT "%s"' % name)
        try:
            yield
        except Exception:
            self.execute('ROLLBACK TO SAVEPOINT "%s"' % name)
            raise
        else:
            self.execute('RELEASE SAVEPOINT "%s"' % name)
    

    그 방법은 문맥이 코드를 더 쉽게, 그것은 것입니다 :

    try:
        with cr.savepoint():
            # your failing query goes here
    except Exception:
        # your alternative code goes here 
    

    거래 물건이 없기 때문에 코드가 더 읽을 수 있습니다.

  4. ==============================

    4.아니면 실패 행이 성공적인 것보다 다른 경로를 가지고 SSIS를 사용 할 수 있습니다.

    아니면 실패 행이 성공적인 것보다 다른 경로를 가지고 SSIS를 사용 할 수 있습니다.

    다른 데이터베이스를 사용하고 있기 때문에 당신은 준비 테이블에 파일 삽입을 대량 후 기존의 ID가없는 레코드 만 선택하는 SQL 코드를 사용할 수 있습니까?

  5. from https://stackoverflow.com/questions/2370328/continuing-a-transaction-after-primary-key-violation-error by cc-by-sa and MIT license