Проверка по внешнему ключу не работает SQLite3 при вводе через discord
Есть три таблицы со связью Многие ко Многим, две primary key и одна связующая их с каскадным обновлением и удалением.
Для удобства понимания:
CREATE TABLE tag_art (
artID INT NOT NULL
REFERENCES art (idA) ON UPDATE CASCADE
ON DELETE CASCADE,
tagID TEXT NOT NULL
REFERENCES tag (idT) ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT fk_tagart PRIMARY KEY (
artID,
tagID
)
);
Если я в sqlite studio или консоль ввожу INSERT INTO tag_art (artID, tagID) VALUES (1, 'test'), то это не сработает, потому что в таблице tag нет значения test в столбце idT. Всё выполняется правильно. Если вместо test введу существующее значения, то оно позволит такой ввод данных.
Суть: это перестаёт работать, если тот же самый запрос поступает не напрямую, а через discord чат и команду. Пример:
import discord
from discord.ext import commands
import sqlite3
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix = '!', intents=intents)
with sqlite3.connect("name.db") as adb:
cur = adb.cursor()
@bot.command()
async def test(ctx):
cur.execute(f"""INSERT INTO tag_art (artID, tagID) VALUES
('1', 'test')
""")
adb.commit()
await ctx.send("Данные успешно приняты!")
bot.run('token')
Такой ввод оно пропускает и вводит значение test, обходя ограничение через внешний ключ, хотя запрос идентичный.
Но если ввести уже существующее значение, то оно его заблокирует и не даст выполнить команду, а значит проверка всё же работает, но только частично. Если вручную затем в программе попробовать изменить это значение на другое неподходящее, то не позволит, как и должно быть.
Если у вас есть идеи почему так происходит, как discord обходит ограничение foreign key и как это можно решить, буду рад любому ответу по делу.
Ответы (1 шт):
Мне удалось найти решение проблемы. Дело в том, что в SQLite3 необходимо включать проверку ограничения по внешним ключам каждый раз, иначе оно будет пропускать любые значения.
Решается буквально одной строчкой, после подключения к базе:
with sqlite3.connect("name.db") as adb:
cur = adb.cursor()
cur.execute("PRAGMA foreign_keys = ON;")
Теперь всё работает верно и выдаёт ошибку, если ввести несуществующие значения. Уверен, многим поможет данная информация.