Per quanto ne so, l'unico modo è per analizzare la stringa di errore nell'eccezione. Non riesco a trovare alcuna tupla che specifica l'errore, la colonna con il vincolo di univocità violata e il valore separatamente.
In particolare, è possibile cercare il messaggio di eccezione utilizzando un operatore di ricerca sottostringa o un'espressione regolare. Per esempio:
db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user))
try:
db.session.commit()
except IntegrityError as err:
db.session.rollback()
if "UNIQUE constraint failed: user.username" in str(err):
return False, "error, username already exists (%s)" % username
elif "FOREIGN KEY constraint failed" in str(err):
return False, "supplier does not exist"
else:
return False, "unknown error adding user"
Tuttavia, queste stringhe può essere abbastanza lungo perché l'istruzione SQL è incluso, per esempio:
(sqlite3.IntegrityError) UNIQUE constraint failed: user.username [SQL: 'INSERT INTO user (username, password_hash, created_time, creator_id, role, is_active, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?)'] [parameters: ('bob', ...
Così, si ridurrà al minimo l'errore di gestione latenze parsing delle eccezioni se si cerca attraverso il messaggio di errore del database, senza le informazioni aggiunte da sqlalchemy. Questo può essere fatto esaminando err.args, che dovrebbero essere più piccolo:
'(sqlite3.IntegrityError) UNIQUE constraint failed: supplier_user.username',)
L'esempio aggiornamento:
db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user))
try:
db.session.commit()
except IntegrityError as err:
db.session.rollback()
err_msg = err.args[0]
if "UNIQUE constraint failed: supplier_user.username" in err_msg:
return False, "error, supplier username already exists (%s)" % username
elif "FOREIGN KEY constraint failed" in err_msg:
return False, "supplier does not exist"
else:
return False, "unknown error adding user"
Nota la sintassi errore che ho usato qui è per sqlite3. Parsing un messaggio di errore di eccezione mysql come:
(1062, "Duplicate entry 'usr544' for key 'username'")
Può essere eseguito con un'espressione regolare appropriata. Si noti che sembra una tupla, ma in realtà è una stringa (sqlalchemy versione 1.1.3 e mysql 5.5).
Ad esempio:
except IntegrityError as err:
db.session.rollback()
if re.match("(.*)Duplicate entry(.*)for key 'username'(.*)", err.args[0]):
.... etc ....
Sì, che è molto utile. Grazie per avermi risparmiato il tempo per estrarlo. –