Executing the RAISE() function in a query raises a sqlite3.IntegrityError exception in the Python code which you can handle like any other exception.
Example script:
import sqlite3
db = sqlite3.connect(':memory:')
db.executescript('''
CREATE TABLE car_park (car);
CREATE TRIGGER car_park_row
BEFORE INSERT ON car_park
WHEN (SELECT count(*) FROM car_park) >= 10
BEGIN
SELECT RAISE (ABORT, 'full');
END;
''')
for i in range(15):
car = f'car{i}'
try:
res = db.execute('insert into car_park values (?)', (car,))
except sqlite3.IntegrityError as e:
print(f'Could not insert {car}: {e}')
for row in db.execute('SELECT * FROM car_park'):
print(row)
Output:
Could not insert car10: full
Could not insert car11: full
Could not insert car12: full
Could not insert car13: full
Could not insert car14: full
('car0',)
('car1',)
('car2',)
('car3',)
('car4',)
('car5',)
('car6',)
('car7',)
('car8',)
('car9',)
(It may be advisable to break out of the loop if an error occurs, it is not done here just for demonstration purposes.)
Instead of printing an error message, you can call any Python function in the exception handler. You do not need to add a user-defined function to the database to do this:
def handle_insert_car_error(car, error):
create_message_box(f'Could not insert {car}: {error}') # or whatever
Then:
# ...
try:
res = db.execute('insert into car_park values (?)', (car,))
except sqlite3.IntegrityError as e:
handle_insert_car_error(car, e)