I am trying to select an array of values from my MySQL without using a for loop. The for loop takes to long and I want to grab all of the values at once. I do not know what is wrong with my arguments and I am having a hard time interpreting what the error message I receive means.
zipcode = ["37204", "60964", "60068"]
connection = MySQLdb.connect(host="localhost", user="root", passwd="password", db="database", cursorclass=MySQLdb.cursors.SSCursor)
cursor = connection.cursor()
query = "SELECT fips FROM us WHERE zip = %s"
cursor.executemany(query,zipcode)
results = cursor.fetchall()
The error looks like this:
query = query % tuple([db.literal(item) for item in args])
TypeError: not all arguments converted during string formatting
Any help is appreciated.
Python is not my forte and I've not used executemany before, but I don't think it's supposed to be used for executing code that's supposed to return something. You probably want to use IN with your query.
query = "SELECT fips FROM us WHERE zip IN ('%s')" % "','".join(zipcode)
cursor.execute(query)
results = cursor.fetchall()
Related
I have a list comprised of several queries which are executed by a for loop. I would like to prompt the user to enter the origin (ilink) that will be utilized by the fourth query in the list.
The script runs fine when the origin is manually defined within the query. I have tried the following syntax which have all failed:
cursor.execute(lines, ilink)
cursor.execute(lines, [ilink])
cursor.execute(lines, (ilink))
I have also run the script with each query defined in its own cursor.execute(query) which accepts the argument, but does not pass any results due to multiple cursors.
import MySQLdb
ilink = raw_input("Choose and ilink to query (include 199N):" )
db = MySQLdb.connect(host="host",user="user",passwd="pass")
queries = [
"""USE monthly_audit;""",
"""DROP TEMPORARY TABLE IF EXISTS monthly_audit.tmp_order_ids;""",
"""DROP TEMPORARY TABLE IF EXISTS monthly_audit.tmp_internalselect;""",
"""CREATE TEMPORARY TABLE monthly_audit.tmp_order_ids AS
(SELECT DISTINCT order_id AS orders
FROM ng_tradeserver_db_history.fix_execution_reports_201906
WHERE FROM_UNIXTIME(TIMESTAMP/1000000) >= '2019-06-19 16:59:59'
AND FROM_UNIXTIME(TIMESTAMP/1000000) <= '2019-06-20 23:59:59'
AND TargetCompID = %s);""",]
cursor = db.cursor()
for lines in queries:
lines.split(",")
cursor.execute(lines, [ilink])
results = cursor.fetchall()
**This is only the relevant snippet of sql, total query is over 500 lines*
I expect the script to run the set of queries and return the results of said query to be stored in a csv. I am currently getting the following error when executing:
_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting
I'm not sure if I understand your questions correct, but you can try using fstrings. I believe the quotes cause the problems during the string formatting.
Example:
query = f'''select ID, lat, lon from tbl order by st_distance(tbl.geom,st_setsrid(st_makepoint({lon},{lat}), 4326)) asc limit 1;'''
cursor.execute(query)
In this query the {lon}, {lat} are variables. Have a look at the docs for f strings https://docs.python.org/3/whatsnew/3.6.html
I'm trying to generate & execute SQL statements via pyodbc. I expect multiple SQL statements, all of which start with the same SELECT & FROM but have a different value in the WHERE. The value in my WHERE clause is derived from looping through a table - each distinct value the SQL script finds in the table, I need Python to generate another SQL statement with this value as the WHERE clause.
I'm almost there with this, I'm just struggling to get pyodbc to put my query strings in formats that SQL likes. My code so far:
import pyodbc
cn = pyodbc.connect(connection info)
cursor = cn.cursor()
result = cursor.execute('SELECT distinct searchterm_name FROM table1')
for row in result:
sql = str("SELECT * from table2 WHERE table1.searchterm_name = {c}".format(c=row)),
#print sql
This code generates an output like this, where "name here" is based on the value found in table1.
('SELECT * from ifb_person WHERE searchterm_name = (u\'name here\', )',)
I just need to remove all the crap surrounding the query & where clause so it looks like this. Then I can pass it into another cursor.execute()
SELECT * from ifb_person WHERE searchterm_name = 'name here'
EDIT
for row in result:
cursor.execute("insert into test (searchterm_name) SELECT searchterm_name FROM ifb_person WHERE searchterm_name = ?",
(row[0],))
This query fails with the error pyodbc.ProgrammingError: No results. Previous SQL was not a query.
Basically what I am trying to do is get Python to generate a fresh SQL statement for every result it finds in table1. The second query is running searches against the table ifb_person and inserting the results to a table "test". I want to run separate SQL statements for every result found in table1
pyodbc allows us to iterate over a Cursor object to return the rows, during which time the Cursor object is still "in use", so we cannot use the same Cursor object to perform other operations. For example, this code will fail:
crsr = cnxn.cursor()
result = crsr.execute("SELECT ...") # result is just a reference to the crsr object
for row in result:
# we are actually iterating over the crsr object
crsr.execute("INSERT ...") # this clobbers the previous crsr object ...
# ... so the next iteration of the for loop fails with " Previous SQL was not a query."
We can work around that by using fetchall() to retrieve all the rows into result ...
result = crsr.execute("SELECT ...").fetchall()
# result is now a list of pyodbc.Row objects and the crsr object is no longer "in use"
... or use a different Cursor object in the loop
crsr_select = cnxn.cursor()
crsr_insert = cnxn.cursor()
crsr_select.execute("SELECT ...")
for row in crsr_select:
crsr_insert.execute("INSERT ...")
This is my code so far. I'm attempting to print No results found if no results are returned by MySQL however I can't figure it out. Perhaps I'm using incorrect arguments. Could anyone provide me with an example? Much appreciated!
def movie_function(film):
connection = mysql connection info
cursor = connection.cursor()
sql = "SELECT * FROM film_database WHERE film_name = '"+film+"' ORDER BY actor"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print row[1]
When you execute a select statement, cursor.rowcount is set to the number of results retrieved. Also, there is no real need to call cursor.fetchall(); looping over the cursor directly is easier:
def movie_function(film):
connection = mysql connection info
cursor = connection.cursor()
sql = "SELECT * FROM film_database WHERE film_name = %s ORDER BY actor"
cursor.execute(sql, (film,))
if not cursor.rowcount:
print "No results found"
else:
for row in cursor:
print row[1]
Note that I also switched your code to use SQL parameters; there is no need to use string interpolation here, leave that to the database adapter. The %s placeholder is replaced for you by a correctly quoted value taken from the second argument to cursor.execute(), a sequence of values (here a tuple of one element).
Using SQL parameters also lets a good database reuse the query plan for the select statement, and leaving the quoting up to the database adapter prevents SQL injection attacks.
You could use cursor.rowcount after your code to see how many rows were actually returned. See here for more.
I guess, this should work.
def movie_function(film):
connection = mysql connection info
cursor = connection.cursor()
sql = "SELECT * FROM film_database WHERE film_name = %s ORDER BY actor"
cursor.execute(sql, [film])
rows = cursor.fetchall()
if not rows:
print 'No resulrs found'
return
for row in rows:
print row[1]
Note, that I changed the way the film parameter is passed to query. I don't know, how exactly it should be (this depends on what MySQL driver for python you use), but important thing to know, is that you should not pass your parameters directly to the query string, because of security reasons.
You can also use :
rows_affected=cursor.execute("SELECT ... ") -> you have directly the number of returned rows
I have a strange problem that Im having trouble both duplicating and solving.
Im using the pyodbc library in Python to access a MS Access 2007 database. The script is basically just importing a csv file into Access plus a few other tricks.
I am trying to first save a 'Gift Header' - then get the auto-incrmented id (GiftRef) that it is saved with - and use this value to save 1 or more associated 'Gift Details'.
Everything works exactly as it should - 90% of the time. The other 10% of the time Access seems to get stuck and repeatedly returns the same value for cur.execute("select last(GiftRef) from tblGiftHeader").
Once it gets stuck it returns this value for the duration of the script. It does not happen while processing a specific entry or at any specific time in the execution - it seems to happen completely
at random.
Also I know that it is returning the wrong value - in other words the Gift Headers are being saved - and are being given new, unique ID's - but for whatever reason that value is not being returned correctly when called.
SQL = "insert into tblGiftHeader (PersonID, GiftDate, Initials, Total) VALUES "+ str(header_vals) + ""
cur.execute(SQL)
gift_ref = [s[0] for s in cur.execute("select last(GiftRef) from tblGiftHeader")][0]
cur.commit()
Any thoughts or insights would be appreciated.
In Access SQL the LAST() function does not necessarily return the most recently created AutoNumber value. (See here for details.)
What you want is to do a SELECT ##IDENTITY immediately after you commit your INSERT, like this:
import pyodbc
cnxn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\Users\\Public\\Database1.accdb;')
cursor = cnxn.cursor()
cursor.execute("INSERT INTO Clients (FirstName, LastName) VALUES (?, ?)", ['Mister', 'Gumby'])
cursor.commit()
cursor.execute("SELECT ##IDENTITY AS ID")
row = cursor.fetchone()
print row.ID
cnxn.close()
Yep! That seems to be a much more reliable way of getting the last id. I believe my initial code was based on the example here http://www.w3schools.com/sql/sql_func_last.asp which I suppose I took out of context.
Thanks for the assist! Here is the updated version of my original code (with connection string):
MDB = 'C:\\Users\\Public\\database.mdb'
DRV = '{Microsoft Access Driver (*.mdb)}'
conn = pyodbc.connect('DRIVER={};DBQ={}'.format(DRV,MDB))
curs = conn.cursor()
SQL = "insert into tblGiftHeader (PersonID, GiftDate, Initials, Total) VALUES "+ str(header_vals) + ""
curs.execute(SQL)
curs.commit()
curs.execute("SELECT ##IDENTITY AS ID")
row = curs.fetchone()
gift_ref = row.ID
I'm having problems with a search in a sqlite3's file, I have a database with columns below:
Title,artist,lyrics,tracking
My code is the is that:
def search(title,artist,query):
if title and artist and query:
db = sqlite3.connect('songs.db')
cursor = db.cursor()
cursor.execute('SELECT ? FROM song WHERE title=? and artist=?',(query,title,artist))
result = cursor.fetchall()
if result:
print result
else:
return False
I have set text_factory to str, but it fix another problem that I had, I have checked the database with a viewer like sqliteman, and tried to search through terminal and it works well. ¿Can anyone see what is wrong?
Parameters in SQL queries are always replaced as fixed values.
In other words, strings are always replaced as strings, not as column names.
To customize column names in your query, you must not use SQL parameters but do the replacement in Python:
cursor.execute('SELECT %s FROM song WHERE title = ? AND artist = ?' % (query),
(title, artist))