質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

3642閲覧

python SQLITEのcursorは前に戻せないのですか

退会済みユーザー

退会済みユーザー

総合スコア0

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/03/24 02:45

タイトル通りの疑問です。

シンプルなことなのですが、

python

1c=conn.cursor 2c.execute(SQL) 3 4for row in c: 5 処理A 6 7for row in c: 8 処理B

このように書くと、Aの時点でカーソルが最後の行に移動してしまい、
Bの処理はできなくなってしまうと思います。

ここで、カーソルを前に戻すというメソッドなどは存在しないのでしょうか。
ドキュメントも一通り眺めて見たつもりなのですがそれらしきものが見当たりませんでした。

また、もし戻せないとすると、再度
c.execute(SQL)
を実行することになるのでしょうか(それも無駄が多いような気がして)。

ご指導よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ここで、カーソルを前に戻すというメソッドなどは存在しないのでしょうか。

はい、PythonのSQLiteはCursor#scrollを実装していないので、存在しません。
pysqliteのcursor.c

fetchone/fetchmany/fetchallがlistを返すので、fetch関数を使う手もあります。

以下はサンプルコードです。

Python

1# -*- coding: utf8 -*- 2import sqlite3 3from contextlib import closing 4 5tablename = 'sample' 6 7 8def insert_data(cur: sqlite3.Cursor) -> None: 9 import random 10 random.seed(42) 11 row_count = 0 12 for i in range(10): 13 sql = f"insert into {tablename} values (?, ?)" 14 params = (i, random.randint(0, 500)) 15 cur.execute(sql, params) 16 row_count += cur.rowcount 17 18 print(f"rowcount:{row_count}") 19 20 21def select_data(cur: sqlite3.Cursor) -> None: 22 sql = f"SELECT * FROM {tablename} ORDER BY id" 23 24 cur.execute(sql) 25 rows = cur.fetchall() 26 for row in rows: 27 print(row) 28 print("#" * 40) 29 for row in rows: 30 print(row) 31 32 33def main() -> None: 34 db_name = 'sample.db' 35 with closing(sqlite3.connect(db_name)) as conn: 36 conn.set_trace_callback(print) 37 cur = conn.cursor() 38 cur.execute(f"drop table if exists {tablename}") 39 cur.execute(f"create table {tablename} (id, rnd)") 40 insert_data(cur) 41 select_data(cur) 42 # コミット忘れに注意! 43 conn.commit() 44 45 46if __name__ == '__main__': 47 main()

投稿2018/03/24 04:00

umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/24 04:23

ありがとうございます。やはり戻せないのですね。ちなみにfetchallと再度executeではパフォーマンスの違いはあるでしょうか。自分で少し試したところ、fetchallがやたらに重かったことがあったので、、。よければお教えください。
umyu

2018/03/24 04:32 編集

>qwdcf_mag 1,executeはジェネレータを返し、fetchallは内部で結果のlistを生成するので、その文メモリを消費します。 2,パフォーマンスが要求される部分に関しては、きちんとプロファイル(cprofile&snakeviz)を取って対応したほうがいいとおもいますー。。 3,PythonのSQLiteが該当するかは分かりませんが、経験則で回答するとSQLiteで重いと仰ってる人に共通するのはSQLiteの暗黙のトランザクションについて知らない人が多いという点ですね。
guest

0

直接の回答ではないですが。

単純な例で書かれていて、実際にはどのようなことをやりたいのかはわかりませんが、

Python

1for row in c: 2 処理A 3 処理B

じゃダメなんですか?同じデータ(群)に対して処理するんですよね?

投稿2018/03/24 03:24

archiver

総合スコア1557

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/24 04:15

ありがとうございます。全く別系統の処理をして2つの出力を出すので、分けたいなという状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問