在sqlite3中启用外键约束

2020年10月22日 / 20次阅读 / Last Modified 2020年10月28日
SQLite

有人说外键约束会降低数据库的速度,据传很多互联网应用都不使用外键,而是通过程序本身的逻辑来保证约束条件。anyway......

SQLite从3.6.19开始支持外键约束,但是默认是关闭的,要通过pragma foreign_keys=on来打开此功能。

如下代码,打开SQLite的外键约束,创建表格,然后测试两个破坏外键约束的情况:

import sqlite3

db = sqlite3.connect(':memory:', isolation_level='exclusive')

db.execute('pragma foreign_keys=on')

db.execute('create table if not exists a1'
           '(id integer primary key, content text)')
db.execute('create table if not exists b1'
           '(id integer references a1(id), content text)')

data = [
    (1,1),
    (2,2),
    (3,3),
    (4,4),
    (5,5)
]

db.executemany('insert into a1 values (?,?)', data)

try:
    db.execute('insert into b1 values (6,6)')
except Exception as e:
    print(repr(e))

db.execute('insert into b1 values (1,1)')

try:
    db.execute('delete from a1 where id=1')
except Exception as e:
    print(repr(e))

#db.commit()

运行这段代码,就能看到外键约束的效果:

IntegrityError('FOREIGN KEY constraint failed')
IntegrityError('FOREIGN KEY constraint failed')

有人说,永远不能相信用户的输入,例如SQL injection攻击。我想说,程序员写的代码能够被信任吗?!如果没有外键约束,数据一致性的保证可能就会成为一个问题。

-- EOF --

本文链接:https://www.pynote.net/archives/2610

留言区

《在sqlite3中启用外键约束》有4条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    外键约束restrict:增加数据时,外键不存在就加不了;删除数据时,有外键引用,删不了。 [回复]

  • 麦新杰

    references table_name,可以写成这样,默认就是使用primary key。此时table_name就必须要有primary key,否则insert into的时候,会有 foreign key mismatch错误!(create table 的时候不会有错) [回复]

  • 麦新杰

    查看某个pgrama参数:

    $ sqlite3 db.table 'pragma foreign_keys;'
    就只不要带上=和后面的值,就是查询。 [回复]

  • 麦新杰

    sqlite3数据库不会记住外键约束,如果在别的线程中connect后,进行一些操作,此时不会默认有foreign_keys=on的效果!因此,要在每一个connect中,确保有代码设置foreign_keys=on。 [回复]


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top