Error with string formatting? - python

Having trouble here, It worked when I had multiple (%s,%s) and data was (user,pass) or something like that.
However with the following code I keep getting this error.
query = query % tuple([db.literal(item) for item in args])
TypeError: not all arguments converted during string formatting
Why does this keep happening? It only occurs when there is only a single argument
This code is from my flask application
username = request.values['username']
update_stmt = (
"UPDATE ACCOUNTS SET IN_USE = 1 WHERE USER = '(%s)'"
)
data = (username)
cursor.execute(update_stmt,data)

For a single valued tuple to be recognized as a tuple you need a trailing ,
data = (username,)
And unrelated, you don't really need to quote in your query
"UPDATE ACCOUNTS SET IN_USE = 1 WHERE USER = (%s)"
Your full code should be
username = request.values['username']
update_stmt = (
"UPDATE ACCOUNTS SET IN_USE = 1 WHERE USER = (%s)"
)
data = (username,)
cursor.execute(update_stmt,data)

Related

How to update postgres array on Python

I selected column "user_list" in 'users' table and fetched to a python variable called "u_list". I appended 'item' in it and tried to update "user_list", but got a lot of errors. I tried searching on stackoverflow, but nothing helped.
code:
cursor.execute(f'SELECT user_list FROM users WHERE id=442392434899681280')
u_list = cursor.fetchone()[0]
u_list.append('item')
cursor.execute('UPDATE users SET user_list = {} WHERE id = 442392434899681280'.format(u_list))
data_base.commit()
but got an error:
Traceback (most recent call last):
File "d:\workspace\sabo\test.py", line 30, in <module>
cursor.execute('UPDATE users SET user_list = {} WHERE id = 442392434899681280'.format(u_list))
psycopg2.errors.SyntaxError: syntax error at or near "["
LINE 1: UPDATE users SET user_list = ['item'] WHERE id = 4423924348996...
Another try and error
code:
cursor.execute(f'SELECT user_list FROM users WHERE id=442392434899681280')
u_list = cursor.fetchone()[0]
u_list.append('item')
cursor.execute("UPDATE users SET user_list= (%s) WHERE id = 442392434899681280", (u_list))
data_base.commit()
error:
File "d:\workspace\sabo\test.py", line 33, in <module>
cursor.execute("UPDATE users SET user_list= (%s) WHERE id = 442392434899681280", (u_list))
psycopg2.errors.InvalidTextRepresentation: malformed array literal: "item"
LINE 1: UPDATE users SET user_list= ('item') WHERE id = 4423924348996...
^
DETAIL: Array value must start with "{" or dimension information.
Think about it like if you were typing the query yourself. As the error statement specifies, to PostgreSQL arrays must star with '{' so they will have to be within curly braces. If you were to write the query in SQL yourself it would look like this:
UPDATE users SET user_list = '{"foo", "bar", "item"}' WHERE id = 442392434899681280;
Handcrafted way
So in Python, it would have to be done like this:
cursor.execute(f'SELECT user_list FROM users WHERE id=442392434899681280')
u_list = cursor.fetchone()[0]
u_list.append('item')
cursor.execute('UPDATE users SET user_list = \'{{{}}}\' WHERE id = 442392434899681280'.format(','.join(['"{}"'.format(v) for v in u_list])))
data_base.commit()
Notice the three curly braces in the formatting, two are to escape so one '{' remains an the third is for the formatting. Also, if your list is not of strings you will have to convert it before joining.
Let psycopg2 handle it
psycopg2's docs also state that Python lists are converted to PostgreSQL ARRAY so the above would be done like like this:
cursor.execute("UPDATE users SET user_list= %s WHERE id = 442392434899681280", (u_list,))
You are missing a comma after the list and there is an extra parentheses surrounding %s in your code sample.

Transfering Data in MS Access Using Python

I have an ever growing and changing database that reflects a permits passed by the State and EPA.
As the database changes and updates I need to transfer the relevant information.
The script does two things; first it checks which fields are the same and creates a list of fields and data that will be inserted into the new database. Second to insert the data into the new database.
Problem is I cannot get it to insert. I have matched everything like it says online in various ways but i get error ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error in INSERT INTO statement. (-3502) (SQLExecDirectW)').
I cannot figure out how to prevent it.
Code:
import pyodbc
importDatabase = r"J:\ENVIRO FIELD\AccessDatabases\MS4\MS4 Town Databases\~Template\MS4_Apocalypse Import DEV 1.accdb"
"Create the Import Database Connection"
connectionImport = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;' %(importDatabase))
cursorImport = connectionImport.cursor()
"####---Outfall Section---####"
"Import the outfall names into the new database"
tbl = "tbl_Outfall_1_Profile"
exportList = []
importList = []
for row in cursorImport.columns(table = "tblExportMigration_Outfall_1_Profile"):
field = row.column_name
exportList.append(field)
for row in cursorImport.columns(table = "tbl_Outfall_1_Profile"):
field = row.column_name
importList.append(field)
matchingList = []
for field in exportList:
if field != "outfallID":
if field in importList:
matchingList.append(field)
else:
continue
sqlValue = ""
for field in matchingList:
sqlValue += "[%s], " %(field)
sqlValue = sqlValue[:-2]
sql = "SELECT %s from %s" %(sqlValue, "tblExportMigration_Outfall_1_Profile")
for rowA in cursorImport.execute(sql):
tupleList = list(rowA)
tupleList = ["" if i == None else i for i in tupleList]
tupleValues = tuple(tupleList)
sqlUpdate = """INSERT INTO tbl_Outfall_1_Profile (%s) Values %s;""" %(sqlValue, tupleValues)
cursorImport.execute(sqlUpdate)
cursorImport.close()
This is the sql string I create
"INSERT INTO tbl_Outfall_1_Profile ([profile_OutfallName], [profile_HistoricalName1], [profile_HistoricalName2], [profile_HistoricalName3], [profile_HistoricalName4]) Values ('756', '', '', '', '');"
Taking what #Gord Thompson said I was actually able to create a dynamic parameter flow
First created a module to create the ?
def Defining_Paramters(length):
parameterString = ""
for x in range(1,length):
parameterString += "?, "
parameterString += "?"
return parameterString
Then stuck it into the string for the sql update
sqlUpdate = sqlUpdate = "INSERT INTO %s (%s) Values (%s);" %(table, sqlFrameworkSubStr, parameters)
Run the cursor and commit it
cursorTo.execute(sqlUpdate, (dataTuple))
connectionTo.commit()
It would seem that you have to create the query in its entirety then have your data in tuple format for entry
This is the sql string [I think] I create
Try this:
sqlUpdate = """INSERT INTO tbl_Outfall_1_Profile (%s) Values (%s);""" %(sqlValue, tupleValues)
or perhaps:
sqlUpdate = "INSERT INTO tbl_Outfall_1_Profile (%s) Values (%s);" %(sqlValue, tupleValues)

Converting data from sqlite3 database into an array format

I have a problem where I am trying to call a specific field from the data recovered by the self.results variable from the sqlite3 login database, although I am unable to do this as I believe that the fetched data is not in an array format and therefore the system is unable to use that field, I got rid of all the " ' ", "(", ")" but I do not know what to do now to convert this text file into an array so that a field can be fetched and printed.
Could you help me?
while True:
username = self.usernameEntry.get()
password = self.passwordEntry.get()
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
findUser = ("SELECT * FROM students WHERE CardNumberID = ? AND Password = ?")
cursor.execute(findUser, [(username), (password)])
self.results = cursor.fetchone()
fetchedResults = str(self.results)
fetchedResults = fetchedResults.replace('(', '')
fetchedResults = fetchedResults.replace(')', '')
fetchedResults = fetchedResults.replace("'", '')
fetchedResults.split(',')
print(fetchedResults[2])
print(self.results)
Here are the results that I get:
The results are in an "array" format, but you then explicitly convert the whole thing to a string. Don't do that.

TypeError: query() argument 1 must be string or read-only buffer, not tuple

I am trying to update the value of a table using Python MySql DB but getting this error.
TypeError: query() argument 1 must be a string or read-only buffer, not tuple.
And I am clueless what is wrong with my answer.
def id_of_unverifedUniversity():
cur3.execute('select id from universities where verified=0 and deleted=0;')
print "===================Unverififed University================"
for row in cur3.fetchall():
#cur3.execute('SELECT id FROM Users where universityId='+str(row['id']))
print row['id']
query = ('SELECT id FROM users where universityId = %s order by id asc limit 1' %(str(row['id'])))
cur3.execute(query)
result = cur3.fetchall()
for y in result:
if y['id']:
print str(y['id'])
print 'update query statred'
query1 = ("""update universities set updatedBy = %s where id=%s""", (str(y['id']),str(row['id'])))
cur3.execute(query1)
i am getting this error in query1
In query1 the operator % seems missed. Which is binding the variables into str
query1 = '''update `universities` set `updatedBy` = %s where `id`=%s''' % (str(y['id']),str(row['id']))
I think you have the wrong formatting for the string replacement in query1, although I'm more familiar with .format().
Try:
query1 = ("""update universities set updatedBy = {} where id={}""".format(str(y['id']),str(row['id'])))
The problem is that your query1 is a tuple.
query1 = ("""update universities set updatedBy = %s where id=%s""", (str(y['id']),str(row['id'])))
I have some comments for you here:
Don't use triple quotes for one-line string.
Use format function
You don't need to cal str to call str method of your object. format or %s will do it for you - will not be superfluous method call.
So your code could be like this one:
query1 = "update universities set updatedBy = {} where id={}".format(y['id'], row['id'])

Python, A MySQL statement works when I put in actual value of variable, but not when using variable?

Have the following code, it is part of a script used to read stdin, and process logs.
jobId = loglist[19]
deliveryCount += 1
dbcur.execute('UPDATE campaign_stat_delivered SET pmta_delivered = pmta_delivered + %s WHERE id = %s') % (deliveryCount,jobId)
dbcon.commit()
dbcon.close()
I can run the following:
dbcur.execute('UPDATE campaign_stat_delivered SET pmta_delivered = pmta_delivered + 1 WHERE id=1')
dbcon.commit()
dbcon.close()
and it will work. Not really sure whats going on, and its hard for me to test quickly because I can't actually see the script running since my program feeds directly into it. I have to make changes, restart program that feeds, send an email, then check database. Have other scripts, and am able to use variables in SQL statements with no problem.
Any suggestions as to what may be going on? And, any suggestions on how I can test quicker?
full code:
import os
import sys
import time
import MySQLdb
import csv
if __name__=="__main__":
dbcon = MySQLdb.connect(host="tattoine.mktrn.net", port=3306, user="adki", passwd="pKhL9vrMN8BsFrJ5", db="adki")
dbcur = dbcon.cursor()
#type, timeLogged,timeQueued,orig,rcpt,orcpt,dsnAction,dsnStatus,dsnDiag,dsnMta,bounceCat,srcType,srcMta,dlvType,dlvSourceIp,dlvDestinationIp,dlvEsmtpAvailable,dlvSize,vmta,jobId,envId,queue,vmtaPool
while True:
line = sys.stdin.readline()
fwrite = open("debug.log","w")
# fwrite.write(str(deliveryCount))
fwrite.write("test2")
dbcur.execute("INSERT INTO test(event_type) VALUES ('list')")
dbcon.commit()
loglist = line.split(',')
deliveryCount = 0
bounceType = loglist[0]
bounceCategory = loglist[10]
email = loglist[4]
jobId = loglist[19]
if bounceType == 'd':
deliveryCount += 1
fwrite = open("debug2.log","w")
# fwrite.write(str(deliveryCount))
fwrite.write("test3")
dbcur.execute("INSERT INTO test(event_type) VALUES (%d)", deliveryCount)
dbcon.commit()
dbcur.execute('UPDATE campaign_stat_delivered SET pmta_delivered = pmta_delivered + %s WHERE id = %s',(deliveryCount,jobId))
dbcon.commit()
dbcon.close()
Never use string interpolation to run a sql query.
You should do:
dbcur.execute(
'UPDATE campaign_stat_delivered SET pmta_delivered = pmta_delivered + %s WHERE id = %s',
(deliveryCount,jobId)
)
There's two arguments to the execute function. The query with placeholders, and a tuple of parameters. This way, mysql will escape your parameters for you and prevent sql injection attacks ( http://en.wikipedia.org/wiki/SQL_injection )
Your error must have come from the fact that you use the % operator on the result of the query 'UPDATE campaign_stat_delivered SET pmta_delivered = pmta_delivered + %s WHERE id = %s'. This query in itself (without parameters) is syntactically incorrect for mysql. You have to pass the tuple of parameters to the execute function as a second argument.

Categories