2014-01-07 12 views
5

私はこのように、SELECT結果を反復処理しています:ループ中に同じカーソルを使用できますか?

import MySQLdb 

conn = MySQLdb.connect(host = 127.0.0.1, user = ...) # and so on 
cur = conn.cursor() 

cur.execute("SELECT * FROM some_table") 

for row in cur: 
    # some stuff I'm doing 
    # sometimes I need to perform another SELECT here 

質問です、私はforループ内で再びcurを使用することができ、または私は別のカーソル(あるいはそれ以上 - 別の接続)を作成する必要があります?

ここでは、データベースやPythonに関する基本的な知識が不足していると思います...私は実際には両方でかなり新しいです。また、Googleの答えに失敗しました。

私は別のカーソルを作成する必要があります。私は間違っている可能性があり、動作するように見える前に、このような時間を実際に使っていたと思います。しかし、私はちょっと混乱しており、保証することはできません。だから私はただ確実にしたい。

ありがとうございます。

+0

あなたは '結果= cur.execute(何とか)'のような何かをして、代わりにresults' 'を反復して、カーソルを再利用することができます。 – IanAuld

答えて

8

新しいカーソルを作成する必要があります。さもなければ、curは今あなたの "外側"の代わりにあなたの新しい "内部"選択の結果を保持しています。

とにかく、あなたのデータベースのライブラリと運に応じて動作しますが、それにはカウントしないでください。私は以下で説明しようとします。

ただし、新しい接続は必要ありません。だから、

cur.execute("SELECT * FROM some_table") 

for row in cur: 
    # some stuff I'm doing 
    inner_cur = conn.cursor() 
    inner_cur.execute("SELECT * FROM other_table WHERE column = row[1]") 
    for inner_row in inner_cur: 
     # stuff 

だから、なぜそれが時々動作しますか?

temp_iter = iter(cur) 
while True: 
    try: 
     row = next(temp_iter) 
    except StopIteration: 
     break 
    # your code runs here 

、は、カーソルオブジェクトの__iter__メソッドを呼び出すこと:

さて、for row in cur:ループが実際にカバーの下に何をするかを見てみましょう。それは何ですか?これは、データベースライブラリによって提供されるカーソルタイプのオブジェクトであるcurまでです。

明白な実装は、カーソルオブジェクトまたはカーソルオブジェクトがカバーの下で使用しているのと同じ行コレクションへの参照を持つ何らかのイテレータを返すことです。これは、例えば、リスト上でiterと呼ぶと起こります。

しかし、__iter__を実装するにはというデータベースライブラリが必要です。はありません。イテレータが使用する行セットのコピーを作成できます。または、より尤度の高い場合は、イテレータが現在の行セットを参照するようにすることができますが、次にexecuteを呼び出すときにと異なるを参照するようにカーソル自体を変更します。 の場合はとなり、古いイテレータは古い行セットを読み続けるので、新しい行セットを反復する新しいイテレータを取得できます。

データベースライブラリーがであることが許可されているため、このようなことに頼るべきではありません。はそうすることができます。しかし、あなたもそれに頼るべきではありません、もちろん起こっていません。より具体的には

、このタイプを想像:

class Cursor(object): 
    # other stuff 
    def __iter__(self): 
     return iter(self.rowset) 
    def execute(self, sql, *args): 
     self.rowset = self.db.do_the_real_work(sql, *args) 
+0

完璧な回答、ありがとうございます。 – zbr

関連する問題