Non credo che SQLite abbia un modo pulito per farlo, quindi sarà necessario utilizzare un'interfaccia di tabella virtuale. SQLite ne fornisce uno per "C" e apsw ne ha uno per Python come dimostrerò di seguito. Ecco la documentazione per lo .
#!/usr/bin/python
import apsw,tempfile
### Opening/creating database
filename=tempfile.mktemp() #insecure - do not use in production code
connection=apsw.Connection(filename)
cursor=connection.cursor()
# This gets registered with the Connection
class Source:
def Create(self, db, modulename, dbname, tablename, *args):
schema="create table foo(dummy integer)"
return schema,Table()
Connect=Create
# Represents a table
class Table:
def __init__(self):
pass
def BestIndex(self, constraints, orderbys):
used = []
self.constraints = []
ucount = 0
for c in constraints:
if c[1] in (
apsw.SQLITE_INDEX_CONSTRAINT_GT,
apsw.SQLITE_INDEX_CONSTRAINT_GE,
apsw.SQLITE_INDEX_CONSTRAINT_LT,
apsw.SQLITE_INDEX_CONSTRAINT_LE,
apsw.SQLITE_INDEX_CONSTRAINT_EQ,
):
used.append(ucount) #tell sqlite we want to use this one
self.constraints.append(c[1]) #save some for later
else:
used.append(None) #skip anything we don't understand
ucount += 1
return (used, # used constraints list
0, # index number - no biggie we only support one right now
)
def Open(self):
return Cursor(self)
def Disconnect(self):
pass
Destroy=Disconnect
# Represents a cursor
class Cursor:
def __init__(self, table):
self.table=table
def Filter(self, indexnum, indexname, constraintargs):
start = 0
self.end = 4000000000
#map constraint arguments to start and end of generation
for tc, ca in zip(self.table.constraints, constraintargs):
if tc == apsw.SQLITE_INDEX_CONSTRAINT_EQ:
start = ca
self.end = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_LE:
if self.end > ca:
self.end = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_LT:
if self.end >= ca:
self.end = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_GE:
if start < ca:
start = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_GT:
if start >= ca:
start = ca
self.pos = start
def Eof(self):
return self.pos > self.end
def Rowid(self):
return self.pos
def Next(self):
self.pos+=1
def Close(self):
pass
# Register the module as intsource, you can make a bunch if needed
connection.createmodule("intsource", Source())
# Create virtual table to use intsource
cursor.execute("create virtual table uints using intsource()")
# Do some counting
for i in cursor.execute("SELECT rowid FROM uints WHERE rowid BETWEEN 1 AND 100"):
print i
Questo implementa un tipo virtuale tabella denominata "intsource", che per i conteggi di default da 0 a 4 * 10^9. Supporta il filtraggio diretto per uguaglianza e comparazione, ma tutti gli altri vincoli saranno ancora filtrati da sqlite. I tavoli virtuali sono un concetto molto potente con cui si può fare molto, questo è probabilmente uno degli usi più semplici per loro. Inoltre, grazie per una buona scusa per provare una nuova API per la tabella virtuale.
sì bene se tabella ' esiste mytable ma non ho un tavolo. –
Perché non creare semplicemente un loop nel linguaggio di programmazione che si sta utilizzando? – BastiBen
C'è qualcosa di sbagliato nella sintassi BETWEEN? – ocodo