Skip to content

Instantly share code, notes, and snippets.

@flaschbier
Created November 8, 2015 17:27
Show Gist options
  • Save flaschbier/151aa6cd81b7a2e6cad7 to your computer and use it in GitHub Desktop.
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
#!/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