2011-01-06 66 views
7

我想我會嘗試讓我的sqlite數據庫連接的功能,而不是複製/粘貼連接和執行查詢所需的〜6行。 我想使它多才多藝,所以我可以使用相同的功能創建/選擇/插入/等...我可以將我的sqlite連接和遊標放在函數中嗎?

以下是我所嘗試過的。 'INSERT'和'CREATE TABLE'查詢正在工作,但是如果我做了'SELECT'查詢,我該如何處理它在函數外部獲取的值?
通常我想打印它提取的值,也可以用它們做其他事情。

當我不喜歡它下面我得到一個錯誤

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. 

所以我猜這個連接必須是開放的,所以我可以從遊標的值,但我需要關閉它,該文件ISN永遠不會鎖定。

這裏是我的測試代碼:

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 

我怎樣才能使這項工作?

編輯:修改了代碼,那麼一點點的CUR值,所以它附加到外部列表中,但仍然很糟糕

回答

15

我認爲這個問題是比起初看上去有點難度。

由於您在「連接」功能中關閉了與數據庫的連接,因此您會看到該錯誤。

您可能最好創建一個DatabaseManagement類來管理單個連接。

喜歡的東西:

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() 

那麼你應該能夠做這樣的事情:

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

這將保持連接打開的對象存在的持續時間。

你仍然可能會發現這是一個更深層次的問題,但請仔細觀察,看看有什麼適用於你。

+0

真棒,我將不得不再次混淆它,但到目前爲止,這個類似乎對我所做的完美工作。謝謝 – 2011-01-06 01:26:13

+1

Minor nit,但你需要:在第二個代碼塊中的for語句後:) – 2017-04-29 14:21:25

0

這是失敗的,因爲你的函數在返回之前關閉連接。解決這個問題的方法是將函數轉換爲傳遞結果的生成器。像下面的未經測試的代碼的東西應該工作:

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() 

你必須要格外小心調用此功能時消耗的所有行,因爲如果你不那麼該連接不會被關閉。您可以通過查看執行with語法所需的功能來避免此問題。