为什么我的sqlite3外键不起作用?

7 投票
2 回答
6957 浏览
提问于 2025-04-16 01:36

我在Python解释器里运行了以下代码,原本期待插入操作会失败并抛出某种异常。但是它并没有这样做:

Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> conn = sqlite3.connect("test.db")
>>> conn.executescript("""
... pragma foreign_keys=on;
... begin transaction;
... create table t1 (i integer primary key, a);
... create table t2 (i, a, foreign key (i) references t1(i));
... commit;
... """)
<sqlite3.Cursor object at 0x0229DAA0>
>>> c = conn.cursor()
>>> c.execute("insert into t2 values (6, 8)")
<sqlite3.Cursor object at 0x0229DAD0>
>>> #???
...
>>> conn.commit()
>>> #???????????
...
>>> c.execute("select * from t2")
<sqlite3.Cursor object at 0x0229DAD0>
>>> c.fetchall()
[(6, 8)]
>>> #but why!?
...
>>>

有没有人知道为什么这不管用?我理解的是,插入应该失败,因为我给的 t2(i) 的值在 t1 中不是主键,但它却照样成功了...?

2 个回答

5

正如尼古拉斯所说,先检查一下你的sqlite版本是否支持外键。如果你的sqlite版本是3.6.19或更高,那就没问题了。不过,有可能你的版本在编译的时候没有开启外键支持。要检查这一点,可以执行以下命令。

cursor.execute("PRAGMA foreign_keys")

如果没有返回任何数据,那说明你的版本不支持外键。

注意:目前sqlite3并没有强制执行外键支持。想了解更多,可以查看这里

9

在SQLite中,外键支持的功能是非常新的——它是在2010年10月14日的3.6.19版本中才发布的。你确定你在使用的是SQLite 3.6.19或更高版本吗?

你可以查看sqlite3模块中的sqlite_version常量来确认。例如,在一个默认安装了python和sqlite的Mac OS X 10.6系统上,你可以这样做:

>>> import sqlite3
>>> sqlite3.sqlite_version
'3.6.12'
>>> 

撰写回答