简体   繁体   中英

How to make ON DELETE CASCADE work in sqlite 3.7.4?

I checked the feature list several times, and it seems that cascading should work. When I execute this python script:

#!/usr/bin/env python3
import sqlite3

print(sqlite3.sqlite_version)

con = sqlite3.connect(':memory:')

a = "create table a (id integer primary key, name text)"
con.execute(a)

b = "create table b (id integer primary key, r integer, foreign key(r) references a(id) on delete cascade)"
con.execute(b)
con.commit()

a = "insert into a (name) values (\"abc\")"
con.execute(a)
con.commit()

print(con.execute("select * from a").fetchall())

a = "insert into b (r) values (1)"
con.execute(a)
con.commit()

print(con.execute("select * from b").fetchall())

a = "delete from a where id=1"
con.execute(a)
con.commit()

print(con.execute("select * from b").fetchall())
print(con.execute("select * from a").fetchall())

I get these results:

3.7.4
[(1, 'abc')]
[(1, 1)]
[(1, 1)]
[]

Which proves that cascading didn't happened. What I did wrong or what are the solutions to get same result as cascading?

SQLite foreign keys are disabled for compatibility purposes. You need to enable them manually right after each connection to the database.

con.execute("PRAGMA foreign_keys = ON")

There's a better answer by user Thibault J over in this question: Enable integrity checking with sqlite in django which says:

from django.db.backends.signals import connection_created
def activate_foreign_keys(sender, connection, **kwargs):
    """Enable integrity constraint with sqlite."""
    if connection.vendor == 'sqlite':
        cursor = connection.cursor()
        cursor.execute('PRAGMA foreign_keys = ON;')

connection_created.connect(activate_foreign_keys)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM