I want to use sqlbuilder (https://sqlbuilder.readthedocs.io/en/latest/) library for building native queries to sqlite. There is my code for inserting data:
import sqlite3
from sqlbuilder.smartsql import Q, T
from sqlbuilder.smartsql.dialects.sqlite import compile
if __name__ == '__main__':
connection = sqlite3.connect(':memory:')
with connection:
connection.execute('CREATE TABLE temp (t TEXT, i INTEGER)')
insert = compile(Q(T.temp).insert({T.temp.t: 'text', T.temp.i: 1}))
sql, params = insert
connection.execute(
sql, params
)
connection.close()
This code does not work, because compile produces incorrect sql and params for sqlite:
('(?, (?, ?))', ['INSERT INTO "temp" ("i", "t") VALUES (%s, %s)', 1, 'text']), and I got the error: sqlite3.OperationalError: near "(": syntax error
Interesting, there is not problems with compiling and executing select statements.
UPDATE:
Code for select statements and it's work:
import sqlite3
from sqlbuilder.smartsql import Q, T
from sqlbuilder.smartsql.dialects.sqlite import compile
if __name__ == '__main__':
connection = sqlite3.connect(':memory:')
with connection:
connection.execute('CREATE TABLE temp (t TEXT, i INTEGER)')
select = compile(Q(T.temp).fields('*'))
print(select) # ('SELECT * FROM `temp`', [])
sql, params = select
connection.execute(
sql, params
)
connection.close()
Answer emended
From the python doc for sqlite3 APIs:
The returned value of
insert` `('(?, (?, ?))', ['INSERT INTO "temp" ("i", "t") VALUES (%s, %s)', 1, 'text'])indicatessqlbuilderis trying to take this advice. What remains is to how to do the string interpolation to put it into valid sqlite syntax. Turns out theresultargument to theQconstructor will do just that.insert = Q(T.temp,result=Result(compile=compile)).insert({T.temp.t: 'text', T.temp.i: 1})will return a tuple that is "SQL ready", ie:('INSERT INTO `temp` (`i`, `t`) VALUES (?, ?)', [1, 'text']). Now you see the '%s' have been replaced by '?'. Don't forget to importResult.