I have created a database with sqlite3, but I can't access and retrieve data by using wildcards.
To retrive the h1 column with the value: Case Samsung Galaxy S9, the wildcard '%?%' doesn't work.
I get the error:
Traceback (most recent call last):
File "regex_query.py", line 13, in <module>
for row in c.execute("SELECT * FROM products WHERE h1 LIKE '%?%' ORDER BY price", (t,)):
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 0, and there are 1 supplied.
This is my code. I tried various iterations the query, but none of them seem to work.
For debugging I also inserted the string "Samsung" straight into the query and it works. By only proble is that
import sqlite3
conn = sqlite3.connect('database.db')
c = conn.cursor()
t = 'Samsung'
for row in c.execute("SELECT * FROM products WHERE h1 LIKE '%?%' ORDER BY price", (t,)):
print row
print c.fetchall()
I have been looking for a solution for hours, but I can't locate where the problem is. Thanks.
I don't think that method works unless you're using a sql that needs VALUES. This should work though
for row in c.execute("SELECT * FROM products WHERE h1 LIKE '%{}%' ORDER BY price".format(t))
Related
I wrote some code to learn SQL databases. My code works fine like I want it to. But I get this error and want to learn what is that.
import sqlite3
con = sqlite3.connect("items.db")
cursor = con.cursor()
cursor.execute("Create table if not exists weapons (name TEXT,ilvl TEXT,source TEXT)")
weapons_txt = open("C:\\Users\\kaytu\\Desktop\\Python\\Exercises\\weapons.txt","r")
for i in weapons_txt:
cursor.execute("Insert into weapons values(?,?,?)",(i.split(";")[0],i.split(";")[1],i.split(";")[2],))
con.commit()
weapons_txt.close()
con.close()
Traceback (most recent call last):
File "c:\Users\kaytu\Desktop\Python\Exercises\Testing.py", line 9, in <module>
cursor.execute("Insert into weapons values(?,?,?)",(i.split(";")[0],i.split(";")[1],i.split(";")[2],))
IndexError: list index out of range
And why do i get the "..." string after every source text? printscreen
this means that at least one of the lines in the txt file has less than two semicolons, check all the lines of the file again
I have the following python code, it reads through a text file line by line and takes characters x to y of each line as the variable "Contract".
import os
import pyodbc
cnxn = pyodbc.connect(r'DRIVER={SQL Server};CENSORED;Trusted_Connection=yes;')
cursor = cnxn.cursor()
claimsfile = open('claims.txt','r')
for line in claimsfile:
#ldata = claimsfile.readline()
contract = line[18:26]
print(contract)
cursor.execute("USE calms SELECT XREF_PLAN_CODE FROM calms_schema.APP_QUOTE WHERE APPLICATION_ID = "+str(contract))
print(cursor.fetchall())
When including the line cursor.fetchall(), the following error is returned:
Programming Error: Previous SQL was not a query.
The query runs in SSMS and replace str(contract) with the actual value of the variable results will be returned as expected.
Based on the data, the query will return one value as a result formatted as NVARCHAR(4).
Most other examples have variables declared prior to the loop and the proposed solution is to set NO COUNT on, this does not apply to my problem so I am slightly lost.
P.S. I have also put the query in its own standalone file without the loop to iterate through the file in case this was causing the problem without success.
In your SQL query, you are actually making two commands: USE and SELECT and the cursor is not set up with multiple statements. Plus, with database connections, you should be selecting the database schema in the connection string (i.e., DATABASE argument), so TSQL's USE is not needed.
Consider the following adjustment with parameterization where APPLICATION_ID is assumed to be integer type. Add credentials as needed:
constr = 'DRIVER={SQL Server};SERVER=CENSORED;Trusted_Connection=yes;' \
'DATABASE=calms;UID=username;PWD=password'
cnxn = pyodbc.connect(constr)
cur = cnxn.cursor()
with open('claims.txt','r') as f:
for line in f:
contract = line[18:26]
print(contract)
# EXECUTE QUERY
cur.execute("SELECT XREF_PLAN_CODE FROM APP_QUOTE WHERE APPLICATION_ID = ?",
[int(contract)])
# FETCH ROWS ITERATIVELY
for row in cur.fetchall():
print(row)
cur.close()
cnxn.close()
I'm working on an application and currently focusing on the database area.
I have successfully setup functions that create databases and write to them, however right now I am trying to retrieve specific rows from the database however NO MATTER WHAT I TRY I always get a syntax error DESPITE my SQL query running successfully in in sqlite browser.
This is my trouble code:
def findapple():
conn = sqlite3.connect('working.db')
c = conn.cursor()
for row in c.execute('SELECT * FROM "working" WHERE "symbol" = 'aapl';')
print row
If I understand the code I've written, it should connect to "working.db" create a cursor for the database then for each row that match my query it should be printed to the console.
Can anyone please help shed some light on this?
Thank you!
Current Code Per comments below:
def findapple():
conn = sqlite3.connect('working.db')
c = conn.cursor()
for row in c.execute('SELECT * FROM working WHERE symbol = 'aapl'')
print row
and the error output:
Traceback (most recent call last):
File "main.py", line 1, in <module>
from stock import *
File "/Users/ME/Documents/Code/Stocks/stock/database.py", line 61
for row in c.execute('SELECT * FROM working WHERE symbol = 'aapl'')
Your string syntax is wrong:
c.execute('SELECT * FROM working WHERE symbol = "aapl"')
I am working with Python 3.3, pypyodbc 1.2.1, and a Quickbooks Enterprise 12 company file being access over Flexquarters QODBC version 14. I'm new to programming and python, so still learning :) I can run a query using the pypyodbc examples just fine, and produces expected results.
Notice the hardcoded email address in the execute. This works as expected:
def get_customer_id(search_col,search_str):
'''(str,str) --> str
>>>get_customer_id(email, foo#foo.com)
80000001-1385782702
'''
cur.execute("SELECT listid FROM CUSTOMER WHERE email='foo#foo.com'")
for row in cur.fetchall():
for field in row:
return field
If I try to do the same thing using the parameters that I am reading from the pypyodbc documentation, I throw an error. I'm having problems with the quotes, and parameter markers I think.
def get_customer_id(search_col,search_str):
'''(str,str) --> str
>>>get_customer_id(email, foo#foo.com)
80000001-1385782702
'''
cur.execute("SELECT listid FROM CUSTOMER WHERE email=?",(search_str,))
for row in cur.fetchall():
for field in row:
return field
Trying to be more pythonistic? I really want to reuse the function to search different columns. Something like:
cur.execute("SELECT listid FROM CUSTOMER WHERE search_str=search_col")
I have looked at a few other threads, and most of them seem to just be dealing with the parameter, and not the column to search. Can anyone help me learn this?
PS forgot to include the traceback:
Traceback (most recent call last):
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 32, in <module>
print(get_customer_id('email','foo#foo.com'))
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 27, in get_customer_id
cur.execute("SELECT listid FROM CUSTOMER WHERE email=?",[search_str,])
File "C:\Python\lib\site-packages\pypyodbc.py", line 1457, in execute
self._BindParams(param_types)
File "C:\Python\lib\site-packages\pypyodbc.py", line 1420, in _BindParams
check_success(self, ret)
File "C:\Python\lib\site-packages\pypyodbc.py", line 982, in check_success
ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
File "C:\Python\lib\site-packages\pypyodbc.py", line 960, in ctrl_err
raise Error(state,err_text)
pypyodbc.Error: ('HY004', '[HY004] [Microsoft][ODBC Driver Manager] SQL data type out of range')
[Finished in 1.7s]
I think the use of
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",[column, email])
can not be accepted by database engine rather than pypyodbc or any other odbc interface. It's the database engine refuse to accept the query for the use of parameter on column names.
Probably you would have to try this instead to reuse the function:
# First construct your dynamic query for the targeted column
sql = """SELECT listid FROM CUSTOMER WHERE %s=?""" %(column)
# Then provide the dynamic value for the dynamic query string
cur.execute(sql, (value,))
Python 3 also has the str.format() method which will do string replacement on {index} items within your string. This is useful if you have many values to inject into your strings like:
myStr = "I like {0} and {1}, but I don't like {2}.".format("apples","bananas","spinach")
myStr
"I like apples and bananas, but I don't like spinach."
# First construct your dynamic query for the targeted column
sql = """SELECT listid FROM CUSTOMER WHERE {0}=?""".format(column)
# Then provide the dynamic value for the dynamic query string
cur.execute(sql, (value,))
It's worth noting that this method of replacing values in a string query can be subject to sql injection.
The safer way to do this would be with parameterized stored procs.
I got 1/2 the answer so far. This works for one parameter, IF I format the string before calling the function;
print(get_custid_email(b'foo#foo.org'))
cur.execute("""SELECT listid FROM CUSTOMER WHERE email=?""",[email])
I still can't get it to do the same thing with column name though.
print(get_custid_email(b'email',b'foo#foo.org'))
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",[column, email])
That throws a differnt error:
Traceback (most recent call last):
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 34, in <module>
print(get_custid_email(b'wendy.lindsay#gmail.com'))
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 29, in get_custid_email
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",['email',email])
pyodbc.ProgrammingError: ('42S00', '[42S00] [QODBC] Data type of parameter cannot be determined (11023) (SQLPrepare)')
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am porting a tcl script to python, because I can't seem to get the tclSqlite thing going on my Nokia N810. The script prompts for inputs, passes them to a sqlite db with 3 tables: Notes, Tags, and a NotesXTags many-to-many tbl. There are triggers that keep me from storing any tags more than once. Being a noob/hobbyist I went line by line through the tcl script replacing each with a Python line. Not very Pythonic, but I'm a hobbyist with no intention of using the language after I get this one script to work on N810. I did look at every Q&A S.O. suggested and I've been working on this for hours. I've got at least 3 bugs-of-ignorance. A chunk of the script in a module called 'pythonmakenote.py':
the crunch-bang ... and some comments ....
import sys, tty
import sqlite3
def mn():
conn = sqlite3.connect('/home/j...notes.sqlite')
db = conn.cursor()
tagsofar =db.execute('select tag_text from tag')
print tagsofar
print "Enter note text, remember to let console wrap long lines"
notetxt = input("note: ")
print "Enter 1 or more tags separated by spaces"
taglist = input("tags: ")
taglist = taglist.split(" ")
db.execute('INSERT INTO note (note_txt) VALUES (?)', notetxt)
db.commit
fknote = db.execute('select last_insert_rowid()')
#records new tags since db trigger stops dups, updates many-many tbl
for tagtxt in taglist:
db.execute('INSERT INTO tag VALUES (?)',tagtxt)
db.commit
fktag = db.execute('select rowid from tag where tag_text = (?)',tagtxt)
db.execute('INSERT INTO fkeys VALUES (?,?)',fknote,fktag)
db.commit
So I do 'import pythonmakenote'. So far so good. I type 'mn' and get an error:
>>> mn
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'mn' is not defined
Then I try this:
>>> from pythonmakenote import mn
>>> mn
<function mn at 0xb76b2a74>
But 'mn' still doesn't work. So I remove the Def altogether and copy the file and name it 'mn.py' and it sort-of works...
>>> import mn
<sqlite3.Cursor object at 0xb75fb740>
Enter note text, remember to let console wrap long lines
note: 'this is a note'<--------------------------Quotes are a MUST (but not in tcl version)
Enter 1 or more tags separated by spaces
tags: 'dev'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mn.py", line 19, in <module>
db.execute('INSERT INTO note (note_txt) VALUES (?)', notetxt)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 14 supplied.<-----------------------------Huh?
Where in the world are the S.O. instructions on code block tags and other markdown?
Why can't I Def mn in a module and use it? Is Python: NameError: global name 'foobar' is not defined pertinent? (to my problem)
I've got several other Defs to do for getting notes by tag, getting the tag list, etc.. and I thought they could all go in one module.
I don't want to put quotes around my inputs (the notes or the space-delimited tag list). Is that doable? I have the import tty thing in there but I'm not using it (don't know how but I'm beginning to suspect I'll have to learn)
If I put 3 tags in when prompted, without quotes, I get the 'unexpected EOF' error. Why?
I see strings are immutable so maybe assigning the list/split to a var that was a string before could be a problem?
Where does sqlite get '14' bindings supplied? I'm splitting on the space char but it's being ignored (because I'm doing it wrong)?
Would it be easier to do my little project in Bash?
Thanks to anyone who takes the time to get this far. I have a bad habit of needing help in areas off-topic in S.U. and too noob-RTFM here. I struggled a little with the tcl version but it now works like a champ. I expected Python to be somewhat straightforward. Still think it might be.
edit: WOW. A bunch of newlines got stripped out. Sorry I have no idea how to fix. I'm off to see if "raw_input" works better.
You'll want raw_input instead of input in your script. input evaluates what you type, which is why you have to enter quotes.
You can markdown code using the {} buttons above the input window. That actual markdown for code is a preceding 4 spaces.
db.commit needs to be db.commit().
If you do this:
>>> import pythonmakenote
To run mn do this:
>>> pythonmakenote.mn()
You can also do:
>>> from pythonmakenote import mn
>>> mn()
For lines like:
db.execute('INSERT INTO note (note_txt) VALUES (?)', notetxt)
You need:
db.execute('INSERT INTO note (note_txt) VALUES (?)', (notetxt,))
execute expects a sequence, so if you pass a string, it acts as a sequence of single characters, hence your 14 bindings error (it was a string of 14 characters). (xxx,) is the syntax for a 1-element tuple. Making it a list [xxx] would work too.
Here's my best guess at something that works. I don't have your database:
import sys
import sqlite3
def mn():
conn = sqlite3.connect('data.db')
db = conn.cursor()
db.execute('select tag_text from tag')
tagssofar = db.fetchall()
print tagssofar
print "Enter note text, remember to let console wrap long lines"
notetxt = raw_input("note: ")
print "Enter 1 or more tags separated by spaces"
taglist = raw_input("tags: ")
taglist = taglist.split()
db.execute('INSERT INTO note (note_txt) VALUES (?)', [notetxt])
conn.commit()
db.execute('select last_insert_rowid()')
fknote = db.fetchone()[0]
print fknote
#records new tags since db trigger stops dups, updates many-many tbl
for tagtxt in taglist:
db.execute('INSERT INTO tag VALUES (?)',[tagtxt])
conn.commit()
db.execute('select rowid from tag where tag_text = (?)',[tagtxt])
fktag = db.fetchone()[0]
print fktag
db.execute('INSERT INTO fkeys VALUES (?,?)',[fknote,fktag])
conn.commit()
There are a couple of things going on here. First, mn does not return anything, you would want something like:
>>> def mn():
... conn = sqlite3.connect('tester.db')
... cur = conn.cursor()
... return cur
...
>>> c = mn()
This leaves an open connection, so when you are done with c you would call:
>>> c.connection.close()
Also, the executing on the cursor does not return anything, you need to call some fetch method, ie fetchone or fetchall. Putting a few of these things together I would start to modify as follows:
import sys, tty
import sqlite3
def mn():
conn = sqlite3.connect('/home/j...notes.sqlite')
cur = conn.cursor()
return cur
db = mn()
tags_so_far = db.execute('select tag_text from tag').fetchall()
print tags_so_far
print "Enter note text, remember to let console wrap long lines \n"
notetxt = raw_input("note: ")
print "Enter 1 or more tags separated by spaces \n"
taglist = raw_input("tags: ").split()
db.execute('INSERT INTO note (note_txt) VALUES (?)', notetxt)
db.commit()
fknote = db.execute('select last_insert_rowid()').fetchone()[0]
#records new tags since db trigger stops dups, updates many-many tbl
for tagtxt in taglist:
db.execute('INSERT INTO tag VALUES (?)', (tagtxt,))
db.commit()
fktag = db.execute('select rowid from tag where tag_text = (?)',tagtxt)
db.execute('INSERT INTO fkeys VALUES (?,?)',fknote,fktag)