2011-01-05 5 views
0

J'essaye de créer une table où j'en ai besoin pour NE PAS permettre des rangées où 3 champs sont identiques.Plusieurs colonnes uniques dans SQLite

Lorsque je crée la table en Python à l'aide de SQLLite, j'utilise ce qui suit, mais je n'obtiens presque aucun résultat. Il s'arrête généralement après avoir écrit 2 enregistrements, donc quelque chose croit évidemment que c'est dupliqué.

CREATE TABLE CorpWalletJournal (
    date INT, 
    refID INT, 
    refTypeID INT, 
    ownerName1 TEXT, 
    ownerID1 INT, 
    ownerName2 TEXT, 
    ownerID2 INT, 
    argName1 TEXT, 
    argID1 ID, 
    amount INT, 
    balance INT, 
    reason TEXT, 
    accountKey INT, 

    UNIQUE (ownerID1, ownerID2, accountKey, argID1) 
); 

Alors, je voudrais la base de données pour ne pas autoriser les enregistrements où ownerID1, ownerID2, AccountKey et argID1 sont les mêmes.

Quelqu'un peut-il m'aider avec cela?

Merci!

+0

* Il s'arrête généralement après avoir écrit 2 enregistrements, donc quelque chose croit évidemment que c'est dupliqué. * - Pourquoi est-ce évident? Quel message d'erreur obtenez-vous lorsque l'insertion échoue? –

+1

Vous n'avez pas spécifié 'NOT NULL' sur les colonnes, alors peut-être que vous obtenez des valeurs nulles qui violent la contrainte unique. À quoi ressemblent les données après l'échec d'une insertion? – Hollister

Répondre

2

Je ne sais pas quel est le problème. Il fonctionne très bien ici:

import sqlite3 

# connect to memory-only database for testing 
con = sqlite3.connect('') 
cur = con.cursor() 

# create the table 
cur.execute(''' 
CREATE TABLE CorpWalletJournal (
    date INT, refID INT, refTypeID INT, ownerName1 TEXT, 
    ownerID1 INT, ownerName2 TEXT, ownerID2 INT, argName1 TEXT, 
    argID1 ID, amount INT, balance INT, reason TEXT, accountKey INT, 
    UNIQUE (ownerID1, ownerID2, accountKey, argID1) 
); 
''') 
con.commit() 

insert_sql = '''INSERT INTO CorpWalletJournal 
(date, refID, refTypeID, ownerName1, ownerID1, ownerName2, ownerID2, 
argName1, argID1, amount, balance, reason, accountKey) 
VALUES 
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''' 

## create 5 rows changing only argID1 - it works: 
for argid in xrange(5): 
    cur.execute(insert_sql, (1, 1, 1, 'a', 1, 'a', 1, 'a', argid, 1, 1, 'a', 1)) 
con.commit() 

# now try to insert a row that is already there: 
cur.execute(insert_sql, (1, 1, 1, 'a', 1, 'a', 1, 'a', 0, 1, 1, 'a', 1)) 

L'erreur que je reçois de la dernière ligne est:

Traceback (most recent call last): 
    File "teststdio.py", line 41, in <module> 
    cur.execute(insert_sql, (1, 1, 1, 'a', 1, 'a', 1, 'a', 0, 1, 1, 'a', 1)) 
sqlite3.IntegrityError: columns ownerID1, ownerID2, accountKey, argID1 
    are not unique 
0

Vous n'êtes pas à la recherche d'unique, mais pour la clé primaire. Lorsque vous définissez PRIMARY KEY (ownerID1, ownerID2, accountKey, argID1), ces 4 valeurs sont l'index de ligne. Cela signifie que si vous écrivez une nouvelle ligne avec ces 4 valeurs égales à une valeur existante, elle écrasera celle-ci. Par conséquent, chaque combinaison des 4 valeurs ne peut exister qu'une seule fois. Par contre, UNIQUE signifie que chacune des 4 valeurs ne peut être utilisée qu'une seule fois.

Questions connexes