Created
November 8, 2015 17:27
-
-
Save flaschbier/151aa6cd81b7a2e6cad7 to your computer and use it in GitHub Desktop.
Using multiple cursors in a nested loop in sqlite3 from python 2.7, RE: http://stackoverflow.com/questions/13237788/using-multiple-cursors-in-a-nested-loop-in-sqlite3-from-python-2-7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python -u | |
# encoding: UTF-8 | |
import sqlite3 | |
import argparse | |
from datetime import datetime | |
DBFILE = 'nested.sqlite' | |
MAX_A = 1000 | |
MAX_B = 10000 | |
parser = argparse.ArgumentParser(description='Nested SQLite cursors in Python') | |
parser.add_argument('step', type=int) | |
args = parser.parse_args() | |
connection = sqlite3.connect(DBFILE) | |
connection.row_factory = sqlite3.Row | |
t0 = datetime.now() | |
if args.step == 0: | |
# set up test database | |
cursor = connection.cursor() | |
cursor.execute("""DROP TABLE IF EXISTS A""") | |
cursor.execute("""DROP TABLE IF EXISTS B""") | |
# intentionally omitting primary keys | |
cursor.execute("""CREATE TABLE A ( K INTEGER )""") | |
cursor.execute("""CREATE TABLE B ( K INTEGER, L INTEGER )""") | |
cursor.executemany("""INSERT INTO A ( K ) VALUES ( ? )""", | |
[ (i,) for i in range(0, MAX_A) ]) | |
connection.commit() | |
for row in cursor.execute("""SELECT COUNT(*) CNT FROM A"""): | |
print row['CNT'] | |
if args.step == 1: | |
# do the nested SELECT and INSERT | |
read = connection.cursor() | |
write = connection.cursor() | |
for row in read.execute("""SELECT * FROM A"""): | |
bs = [ ( row['K'], i ) for i in range(0, MAX_B) ] | |
for b in bs: # with .executemany() it would be twice as fast ;) | |
write.execute("""INSERT INTO B ( K, L ) VALUES ( ?, ? )""", b) | |
connection.commit() | |
for row in connection.cursor().execute("""SELECT COUNT(*) CNT FROM B"""): | |
print row['CNT'] | |
elif args.step == 2: | |
connection = sqlite3.connect(DBFILE) | |
connection.row_factory = sqlite3.Row | |
control = connection.cursor() | |
ca = cb = 0 # will count along our expectation | |
for row in control.execute("""SELECT * FROM B ORDER BY K ASC, L ASC"""): | |
assert row['K'] == ca and row['L'] == cb | |
cb += 1 | |
if cb == MAX_B: | |
cb = 0 | |
ca += 1 | |
assert ca == MAX_A and cb == 0 | |
for row in connection.cursor().execute("""SELECT COUNT(*) CNT FROM B"""): | |
print row['CNT'] | |
print datetime.now() - t0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment