sqlite3外键“记得”?

时间:2012-02-18 16:13:15

标签: python sqlite

我真的,真的希望我只是做错了。

我有两个表和一个映射表;后者的两列引用其他列的相应主键。如果存在映射,则删除其中一个数据行不起作用;这是预料之中的。但是,删除映射应该允许我删除数据行,但是当我尝试删除时会出现IntegrityError。

示例代码:

import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('PRAGMA foreign_keys = ON')
fk = (conn.execute("PRAGMA foreign_keys").fetchone()[0])
print 'version = %s, foreign keys = %r' % (sqlite3.sqlite_version, bool(fk))
if not fk:
  raise Exception('No foreign keys!?')

c = conn.cursor()
c.executescript('''
create table if not exists main.one (resource_id TEXT PRIMARY KEY, data TEXT);
create table if not exists main.two (node_id INTEGER PRIMARY KEY, data TEXT);
create table if not exists main.mapping (node_id INTEGER REFERENCES two, resource_id TEXT REFERENCES one);
insert into main.one(resource_id, data) values('A', 'A one thing');
insert into main.two(node_id, data) values(1, 'A two thing');
insert into main.mapping(resource_id, node_id) values('A', 1);
insert into main.one(resource_id, data) values('B', 'Another one thing');
insert into main.two(node_id, data) values(2, 'Another two thing');
insert into main.mapping(resource_id, node_id) values('B', 2);
insert into main.one(resource_id, data) values('C', 'Yet another one thing');
''')
for tbl in 'one', 'two', 'mapping':
  print 'TABLE main.%s:\n%s\n' % (tbl, '\n'.join(repr(r) for r in c.execute('select * from main.%s' % tbl).fetchall()))

del_cmd = """delete from main.one where resource_id='B'"""
print 'Attempting: %s' % (del_cmd,)
try:
  c.execute(del_cmd)
except Exception, e:
  print 'Failed to delete: %s' % e

cmd = """delete from main.one where resource_id='C'"""
print 'Attempting: %s' % (cmd,)
c.execute(cmd)

cmd = """delete from main.mapping where resource_id='B' AND node_id=2"""
print '\nAttempting: %s' % (cmd,)
c.execute(cmd)

for tbl in 'one', 'two', 'mapping':
  print 'TABLE main.%s:\n%s\n' % (tbl, '\n'.join(repr(r) for r in c.execute('select * from main.%s' % tbl).fetchall()))

print 'Attempting: %s' % (del_cmd,)
c.execute(del_cmd)                                                                                                                                             

我希望所有这些都可以打印各种表格内容和进度。但是,最后一个DELETE违反了我找不到的外键约束:

$ python test.py                                                                                                                                               
version = 3.6.22, foreign keys = True
TABLE main.one:
(u'A', u'A one thing')
(u'B', u'Another one thing')
(u'C', u'Yet another one thing')

TABLE main.two:
(1, u'A two thing')
(2, u'Another two thing')

TABLE main.mapping:
(1, u'A')
(2, u'B')

Attempting: delete from main.one where resource_id='B'
Failed to delete: foreign key constraint failed
Attempting: delete from main.one where resource_id='C'

Attempting: delete from main.mapping where resource_id='B' AND node_id=2
TABLE main.one:
(u'A', u'A one thing')
(u'B', u'Another one thing')

TABLE main.two:
(1, u'A two thing')
(2, u'Another two thing')

TABLE main.mapping:
(1, u'A')

Attempting: delete from main.one where resource_id='B'
Traceback (most recent call last):
  File "/tmp/test.py", line 49, in <module>
    c.execute(del_cmd)
sqlite3.IntegrityError: foreign key constraint failed

WTF?

0 个答案:

没有答案