2017-01-05 2 views
0

이것은 간단한 질문입니다. 저는 SQLAlchemy를 가지고 놀았으며 지금은 테이블의 고유 제한 조건을 다루는 시점에 있습니다. 따라서 고유 제약 조건을 위반하면 IntegrityError 예외가 발생합니다. 테이블에 대해 여러 개의 고유 제한 조건이 정의되어있는 경우 발생하는 예외를 통해 어떻게 구별 할 수 있습니까?무결성 오류가 발생할 때 다른 고유 제약 조건을 구별하는 방법

편집 : 아래에 sqlite3이 사용됩니다.

최종 편집 : AVC 응답은 제약 조건을 위반 한 열에 대한 메시지 오류를 확인하여 대체 솔루션을 제공합니다. 그것은 우아한 해결책은 아니지만 일을 끝내게합니다.

+0

참조 [android.database.SQLException에서 오류 세부 정보를 얻는 방법?] (http://stackoverflow.com/questions/35637570/how-to-get-errors-details-from-android-database-sqlexception) –

+0

도움이되지 않습니다. Android 나 Java를 사용하지 않습니다. – Claymore

답변

1

무결성 오류로 어떤 열이 제약 조건을 위반했는지 알 수 있습니다. example의 경우 :

IntegrityError: (IntegrityError) insert or update on table "my_table" 
      violates foreign key constraint "my_table_some_column_fkey" 

귀하의 경우에는이처럼 제약 조건을 선언하는 : 당신이 여기서하고있는 것은 여러 고유성 제약을 선언 하지이다

UniqueConstraint('datapath_port_id', 'datapath_id', 
    'controller_id', name='unique_registration') 

. 대신 당신이 조합 세 열의은 고유해야한다는 것을 의미 다중 열 또는 복합 고유성 제약 조건을 만든

Column('datapath_port_id', unique=True) 
Column('datapath_id', unique=True) 
Column('controller_id', unique=True) 

: 그것은 다음과 같이 보일 것입니다.

복수 열 고유성 제약 조건이있는 A, B, C 데이터베이스 행이있는 경우 이미 첫 번째 행에 A 값이 있더라도 A, A, A을 삽입 할 수 있습니다. 마찬가지로 B, B, BC, C, C도 유효 삽입물입니다. 그래도 A, B, C을 다시 삽입하려고하면 실패합니다. 모든 열이 기존 행과 일치하기 때문에 오류가 발생합니다. 그 이유는보고있는 고유성 오류가 모든 열을 나열하는 이유입니다. 우리가 어떻게되는지 다른 고유성 제약 조건을 위반하는 시도 할 수 있습니다 거기에서

from sqlalchemy import create_engine 
from sqlalchemy import Column, Integer 
from sqlalchemy import UniqueConstraint 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import sessionmaker 

engine = create_engine('sqlite:///:memory:', echo=True) 
Base = declarative_base() 


class Test(Base): 
    __tablename__ = 'test' 
    __table_args__ = (
     UniqueConstraint('a', 'b', name='ab_constraint'), 
     UniqueConstraint('b', 'c', name='bc_constraint')) 
    id = Column(Integer, primary_key=True) 
    a = Column(Integer) 
    b = Column(Integer) 
    c = Column(Integer) 


Base.metadata.create_all(engine) 
Session = sessionmaker(bind=engine) 
session = Session() 

session.add(Test(a=1, b=1, c=1)) 
session.add(Test(a=2, b=2, c=2)) 

: 여기

은 코드 예입니다. 이 명령을 실행하려고하면 :

sqlalchemy.exc.IntegrityError: (IntegrityError) UNIQUE constraint failed: test.a, test.b u'INSERT INTO test (a, b, c) VALUES (?, ?, ?)' (1, 1, 2) 

을 우리가 두 번째 제약 조건 위반하려고하면 다음 :

session.add(Test(a=1, b=1, c=2)) 
session.commit() 

을 우리는 얻을

session.add(Test(a=1, b=2, c=2)) 
session.commit() 

을 우리가 대신받을 :

sqlalchemy.exc.IntegrityError: (IntegrityError) UNIQUE constraint failed: test.b, test.c u'INSERT INTO test (a, b, c) VALUES (?, ?, ?)' (1, 2, 2) 

첫 번째 경우로 0을 지정하면및 test.b은 제약 조건을 위반했으며 두 번째 것은 test.btest.c을 지정했습니다.

내가 그 제약 (ab_constraintbc_constraint)에 대한 선택이름은 그러나 응답에 포함되지 않습니다 있습니다. 그들은 이지만 데이터베이스 레벨에 있습니다. 우리는 데이터베이스 생성을 메아리하여이 볼 수있는 것은 명령 :

CREATE TABLE test (
    id INTEGER NOT NULL, 
    a INTEGER, 
    b INTEGER, 
    c INTEGER, 
    PRIMARY KEY (id), 
    CONSTRAINT ab_constraint UNIQUE (a, b), 
    CONSTRAINT bc_constraint UNIQUE (b, c) 
) 

그러나, 데이터베이스 레벨 (I SQLite는을 사용하고 있습니다) 제한 조건 이름이 오류 메시지에 사용하지 않을시 :

sqlite> INSERT INTO test (a, b, c) VALUES (1, 1, 1); 
sqlite> INSERT INTO test (a, b, c) VALUES (2, 2, 2); 
sqlite> INSERT INTO test (a, b, c) VALUES (1, 1, 2); 
Error: UNIQUE constraint failed: test.a, test.b 
+0

내 제약에 대한 결과가 나에게 반환되지 않았기 때문에 이것은 이상합니다. 나는 밑에 sqlite3을 사용하고 있다는 것을 언급하는 것을 잊었다. 이것은 고유 제한 조건의 결과입니다. '(sqlite3.IntegrityError) UNIQUE 제약 조건이 실패했습니다 : hosts.datapath_port_id, hosts.datapath_id, hosts.controller_id [SQL : 'INSERT INTO 호스트 (host_mac, datapath_port_id, datapath_id, controller_id, registration_date) VALUES (?,?,?,? , '?]'] [매개 변수 : ('AA-BB-CC-DD-EE-FF', 1, 1, 1, '2017-01-06 15 : 06 : 38.429267')] ' – Claymore

+0

constaint가 선언되었습니다. 'UniqueConstraint ('datapath_port_id ','datapath_id ','controller_id ', name ='unique_registration '),' – Claymore

+0

혼란의 근원을 이해하고 대답을 업데이트했으며 도움이되는지 알려주세요. – ACV

관련 문제