No creo que SQLite tenga una forma clara de hacerlo, por lo que deberá usar una interfaz de tabla virtual. SQLite envía uno para 'C', y apsw tiene uno para python, como demostraré a continuación. Aquí hay documentación para el .
#!/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
Esto implementa un tipo virtual tabla llamada "intsource", que mediante el recuento por defecto de 0 a 4 x 10^9. Es compatible con el filtrado directo por igualdad y comparación, pero cualquier otra restricción seguirá siendo filtrada por sqlite. Las tablas virtuales son un concepto muy poderoso con el que puedes hacer mucho, este es probablemente uno de los usos más simples para ellos. Además, gracias por una buena excusa para probar una nueva tabla virtual API.
sí bien si tabla ' mytable' existe pero no tengo una tabla en absoluto. –
¿Por qué no simplemente crear un bucle en el lenguaje de programación que está utilizando? – BastiBen
¿Hay algún problema con la sintaxis BETWEEN? – ocodo