2011-01-06 6 views
7

私はsqlite db接続をコピーして、代わりに〜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

「接続」機能でデータベースへの接続を終了したため、エラーが表示されます。

1つの接続を管理するためにDatabaseManagementクラスを作成するほうが良いでしょう。以下のような

何か:

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

これは、オブジェクトの存在の間、接続を開いたままになります。

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

次に、あなたのような何かを行うことができるはず。

これはさらに深刻な問題であることがわかりますが、何が効果的かを見てみましょう。

+0

素晴らしい、私はもう少しそれを取り巻く必要がありますが、これまでのところ、このクラスは私がやっていることを完全に動作するようです。ありがとう –

+1

マイナーニトロ、しかし必要:あなたの2番目のコードブロックのfor文の後:) –

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構文に必要な機能を実装することで、この問題を回避できます。