2010-07-21 31 views
6

Tôi chạy đoạn mã sau từ trình thông dịch trăn, và mong đợi câu lệnh chèn không thành công và ném một loại ngoại lệ nào đó. Nhưng điều này không xảy ra:Tại sao khóa ngoài của sqlite3 không hoạt động?

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!? 
... 
>>> 

Có ai biết tại sao điều này không muốn hoạt động không? Sự hiểu biết của tôi là chèn nên thất bại vì giá trị tôi đã cho t2(i) không phải là một khóa chính trong t1, nhưng nó vui vẻ làm điều đó anyway ...?

Trả lời

10

Hỗ trợ khóa ngoài hoạt động trong SQLite rất mới - nó chỉ được phát hành trong 3.6.19 vào ngày 14 tháng 10. Bạn có chắc là bạn đang sử dụng SQLite 3.6.19 hoặc mới hơn?

Kiểm tra hằng số sqlite_version trong mô-đun sqlite3. Ví dụ. trên Mac OS X 10.6 hệ thống với mặc định python/sqlite cài đặt:

>>> import sqlite3 
>>> sqlite3.sqlite_version 
'3.6.12' 
>>> 
+0

Tôi định nói rằng phải, vì tôi có thể làm cho nó hoạt động với trình thông dịch tương tác sqlite, nhưng sau đó tôi nhận ra rằng python có sqlite riêng của nó được xây dựng - Tôi phải có một cái mới trên hệ thống của mình nhưng không có python của tôi. Cảm ơn –

+0

Ah, bạn đã đúng, tôi có 3.5.9. –

2

Như đã nói bởi Nicholas, kiểm tra xem phiên bản của sqlite đã hỗ trợ chính nước ngoài. Điều này không quan trọng nếu phiên bản của sqlite lớn hơn hoặc bằng 3.6.19. Nguồn có thể được biên dịch với hỗ trợ khóa ngoài được tắt. Để kiểm tra thực thi lệnh sau đây.

cursor.execute("PRAGMA foreign_keys")

Nếu không trả lại bất kỳ dữ liệu nào thì phiên bản của bạn không hỗ trợ khóa ngoài.

NB: Hỗ trợ khóa ngoài không được thực thi trong sqlite3 như bây giờ. Hãy xem here.

+1

Phải không? Trong sqlite 3.8.10 nó dường như để thực thi nó tốt với pragma Foreign_keys bật –

+0

Theo tài liệu của họ, nó không. Hiện tại tôi không tìm thấy lý do nào để nghi ngờ điều đó, bởi vì db của tôi hoạt động giống như vậy. Dù sao tôi sẽ kiểm tra phiên bản 3.8.10. – Charitoo

+1

Tôi đã thử nó với mô-đun sqlite3 cài đặt python 3.5 của tôi (sử dụng 3.8.11) và các ràng buộc khoá ngoài được hỗ trợ ở đó. Vi phạm cho tôi một 'sqlite3.IntegrityError: Ràng buộc KEY FOREIGN thất bại' –

Các vấn đề liên quan