三个表具有多对多关系,两个主键和一个通过级联更新和删除链接它们。
为了便于理解:
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 或 console INSERT INTO tag_art (artID, tagID) VALUES (1, 'test'),它将不起作用,因为标记表在 idT 列中没有测试值。一切都正确完成。如果我输入现有值而不是测试,那么它将允许输入此类数据。
底线:如果相同的请求不是直接发出的,而是通过不和谐的聊天和团队发出的,这将停止工作。例子:
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')
它跳过这样的输入并进入值测试,绕过外键约束,尽管请求是相同的。
但是如果你输入一个已经存在的值,那么它会阻止它并阻止命令被执行,这意味着检查仍然有效,但只是部分有效。如果您随后手动尝试将此值更改为程序中另一个不合适的值,它将不允许,因为它应该是。
如果您知道为什么会发生这种情况,discord 如何绕过外键限制以及如何解决,欢迎对此案的任何回答。
我设法找到了解决问题的方法。关键是在 SQLite3 中,您每次都需要包含外键约束检查,否则它将跳过任何值。
在连接到数据库后,它是在一行中解决的:
现在一切正常,如果您输入不存在的值,则会出现错误。我相信这些信息会对很多人有所帮助。