2011-01-06 32 views
7

Tôi đã nghĩ tôi sẽ cố gắng tạo kết nối db sqlite của mình thành một hàm thay vì sao chép/dán ~ 6 dòng cần thiết để kết nối và thực hiện truy vấn trên khắp nơi. Tôi muốn làm cho nó linh hoạt để tôi có thể sử dụng chức năng tương tự để tạo/chọn/chèn/v.v ...Tôi có thể đặt kết nối sqlite và con trỏ của tôi vào một hàm không?

Dưới đây là những gì tôi đã thử. Các truy vấn 'INSERT' và 'CREATE TABLE' đang hoạt động, nhưng nếu tôi thực hiện truy vấn 'SELECT', làm cách nào tôi có thể làm việc với các giá trị mà nó tìm nạp bên ngoài hàm?
Thông thường tôi muốn in các giá trị mà nó tìm nạp và cũng làm những việc khác với chúng.

Khi tôi làm điều đó như dưới đây, tôi nhận được một lỗi

Traceback (most recent call last): 
File "C:\Users\steini\Desktop\py\database\test3.py", line 15, in <module> 
for row in connection('testdb45.db', "select * from users"): 
ProgrammingError: Cannot operate on a closed database. 

Vì vậy, tôi đoán các kết nối cần phải được mở để tôi có thể nhận các giá trị từ con trỏ, nhưng tôi cần phải đóng nó để file isn 't luôn luôn bị khóa.

Đây là mã thử nghiệm của tôi:

import sqlite3 

def connection (db, arg, cubby): 
    conn = sqlite3.connect(db) 
    conn.execute('pragma foreign_keys = on') 
    cur = conn.cursor() 
    cur.execute(arg) 
    for row in cur: 
     cubby.append(row) 
    conn.commit() 
    conn.close() 

cubby=[] 
connection('testdb.db', "create table users ('user', 'email')", cubby) 
connection('testdb.db', "insert into users ('user', 'email') values ('joey', '[email protected]')", cubby) 
for row in connection('testdb45.db', "select * from users", cubby): 
    print row 

Làm thế nào tôi có thể làm công việc này?

EDIT: sửa đổi mã một chút để các giá trị cur vì vậy nó gắn vào một danh sách bên ngoài, nhưng vẫn còn khá xấu

Trả lời

15

Tôi nghĩ vấn đề là một chút khó khăn hơn nó nhìn vào đầu tiên.

Bạn đang gặp lỗi vì bạn đã đóng kết nối của mình với cơ sở dữ liệu trong chức năng "kết nối" của bạn.

Có lẽ bạn nên tạo một lớp DatabaseManagement, để quản lý một kết nối duy nhất.

Cái gì như:

import sqlite3 

class DatabaseManager(object): 
    def __init__(self, db): 
     self.conn = sqlite3.connect(db) 
     self.conn.execute('pragma foreign_keys = on') 
     self.conn.commit() 
     self.cur = self.conn.cursor() 

    def query(self, arg): 
     self.cur.execute(arg) 
     self.conn.commit() 
     return self.cur 

    def __del__(self): 
     self.conn.close() 

Sau đó, bạn sẽ có thể làm điều gì đó như:

dbmgr = DatabaseManager("testdb.db") 
for row in dbmgr.query("select * from users"): 
    print row 

Điều này sẽ giữ kết nối mở trong suốt thời gian tồn tại của đối tượng.

Bạn vẫn có thể thấy đây là vấn đề sâu hơn, nhưng hãy chơi xung quanh và xem những gì phù hợp với bạn.

+0

tuyệt vời, tôi sẽ phải làm phiền với nó một số chi tiết, nhưng cho đến nay lớp học này dường như hoạt động hoàn hảo cho những gì tôi đang làm. Cảm ơn –

+1

Nit nhỏ, nhưng bạn cần: sau câu lệnh for trong khối mã thứ hai của bạn :) –

0

Không thành công vì chức năng của bạn đóng kết nối trước khi trở về. Cách để khắc phục điều này là biến chức năng thành một trình tạo và truyền các kết quả. Nội dung nào đó giống như mã chưa được kiểm tra sau đây sẽ hoạt động:

def connection (db, arg): 
    conn = sqlite3.connect(db) 
    conn.execute('pragma foreign_keys = on') 
    cur = conn.cursor() 
    cur.execute(arg) 
    for row in cur: 
     yield row 
    conn.commit() 
    conn.close() 

Bạn phải cẩn thận khi tiêu thụ tất cả các hàng khi gọi chức năng này, bởi vì nếu không thì kết nối sẽ không bị đóng. Bạn có thể tránh được vấn đề này bằng cách xem xét việc triển khai các hàm cần thiết cho cú pháp with.

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