如何从 SQLite 触发器调用 Python 函数

How to call a Python function from a SQLite trigger

这是我的触发器

cursor.execute(
 '''CREATE TRIGGER IF NOT EXISTS Car_Park_row_
    BEFORE INSERT ON Car_Park
    WHEN (SELECT COUNT(*) FROM Car_PARK) >= 10
    BEGIN
        SELECT RAISE (ABORT, 'FULL');
        
        END;

这是我的职能

def C(x):
    print('Error')

# Create Database
connector = sqlite3.connect('cparks.db')
connector.create_function("sql", -1, C)
cursor = connector.cursor()

我已使用触发器将数据库中的行数限制为 10。我现在需要的是一个消息框或类似的东西,让 GUI 用户知道 table 已满。

在查询中执行 RAISE() 函数会在 Python 代码中引发 sqlite3.IntegrityError 异常,您可以像处理任何其他异常一样处理该异常。

示例脚本:

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)

输出:

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',)

(如果发生错误,可能建议 break 跳出循环,这里不这样做只是为了演示。)

您可以调用异常处理程序中的任何 Python 函数,而不是打印错误消息。您不需要向数据库添加用户定义的函数来执行此操作:

def handle_insert_car_error(car, error):
    create_message_box(f'Could not insert {car}: {error}')  # or whatever

然后:

# ...
    try:
        res = db.execute('insert into car_park values (?)', (car,))
    except sqlite3.IntegrityError as e:
        handle_insert_car_error(car, e)