2013-06-01 19 views
7

SQLite có Data Change Notification Callbacks có sẵn trong API C. Những callbacks này có thể được sử dụng từ CLI SQLite hay từ Bash hoặc từ Python không?Số lần gọi lại thông báo thay đổi dữ liệu SQLite bằng Python hoặc Bash hoặc CLI

Nếu có, làm cách nào?

+1

từ Go lang ... https://godoc.org/code.google.com/p/go-sqlite/go1/sqlite3#Conn.UpdateFunc – Anentropic

+1

Trên PyPI, apsw có các liên kết: http: // rogerbinns. github.io/apsw/connection.html#apsw.Connection.setupdatehook – GrantJ

Trả lời

12

những callbacks Có thể sử dụng từ SQLite CLI ...

Đọc qua mã nguồn SQLite, nó không giống như vậy chức năng được sử dụng bất cứ nơi nào trong mã nguồn CLI, vì vậy tôi nghi ngờ bạn có thể làm điều đó thông qua CLI.

... hoặc từ Bash ...

Không chắc chắn những gì bạn có nghĩa là bằng cách đó.

... hoặc từ Python?

Không được hiển thị qua mô-đun sqlite3 tiêu chuẩn, nhưng bạn có thể sử dụng mô-đun này với mô-đun ctypes.

Nếu có, làm cách nào?

Dưới đây là một n nhanh chóng' dụ bẩn của việc sử dụng nó thông qua ctypes ...

from ctypes import * 

# Define some symbols 
SQLITE_DELETE = 9 
SQLITE_INSERT = 18 
SQLITE_UPDATE = 23 

# Define our callback function 
# 
# 'user_data' will be the third param passed to sqlite3_update_hook 
# 'operation' will be one of: SQLITE_DELETE, SQLITE_INSERT, or SQLITE_UPDATE 
# 'db name' will be the name of the affected database 
# 'table_name' will be the name of the affected table 
# 'row_id' will be the ID of the affected row 
def callback(user_data, operation, db_name, table_name, row_id): 
    if operation == SQLITE_DELETE: 
     optext = 'Deleted row' 
    elif operation == SQLITE_INSERT: 
     optext = 'Inserted row' 
    elif operation == SQLITE_UPDATE: 
     optext = 'Updated row' 
    else: 
     optext = 'Unknown operation on row' 
    s = '%s %ld of table "%s" in database "%s"' % (optext, row_id, table_name, db_name) 
    print s 

# Translate into a ctypes callback 
c_callback = CFUNCTYPE(c_void_p, c_void_p, c_int, c_char_p, c_char_p, c_int64)(callback) 

# Load sqlite3 
dll = CDLL('libsqlite3.so') 

# Holds a pointer to the database connection 
db = c_void_p() 

# Open a connection to 'test.db' 
dll.sqlite3_open('test.db', byref(db)) 

# Register callback 
dll.sqlite3_update_hook(db, c_callback, None) 

# Create a variable to hold error messages 
err = c_char_p() 

# Now execute some SQL 
dll.sqlite3_exec(db, 'create table foo (id int, name varchar(255))', None, None, byref(err)) 
if err: 
    print err.value 
dll.sqlite3_exec(db, 'insert into foo values (1, "Bob")', None, None, byref(err)) 
if err: 
    print err.value 

... mà in ra ...

Inserted row 1 of table "foo" in database "main" 

... vào ngày đầu tiên chạy và ...

table foo already exists 
Inserted row 2 of table "foo" in database "main" 

... trong lần chạy thứ hai.

+1

"Không chắc chắn ý bạn là gì." Ý tôi là, từ một kịch bản Bash; ví dụ. một trình bao bọc CLI SQLite, hoặc chặn các đối số/tùy chọn được chuyển tới lệnh 'sqlite3'. – sampablokuper

+0

N.B. Dòng của bạn 'dll = CDLL ('libsqlite3.so')' có thể cần trên một số nền tảng được thay đổi thành 'dll = CDLL ('libsqlite3.0.dylib')' – sampablokuper

+1

@sampablokuper Về nhận xét tập lệnh bash: CLI SQLite không Không sử dụng hàm 'sqlite3_update_hook()' ở bất kỳ đâu trong mã của nó, vì vậy tôi không thấy cách bạn có thể làm điều đó bằng cách sử dụng một tập lệnh bash chỉ bao bọc/chặn lệnh 'sqlite3'. – Aya