I am trying to update a row of a Postgresql table. I am using Psycopg2 and Python3.
I receive the error:
"TypeError: not all arguments converted during string formatting"
code:
self.cursor.executemany("INSERT INTO blacklisted_ips (ip, source_id, date_created, date_modified) VALUES (%s, %s, %s, %s);", ["address_list"])
ip, source_id, date_created, date_modified are the column names.
passing a list of tuples
address_list sample data:
('223.223.202.183', 29, '2018-06-28 12:32:02', '2018-06-28 12:32:02')
I can't figure out why I get this error. I'm guessing it is centered around the place holders after "VALUES". Any help is greatly appreciated.
Assuming address_list is a list of values to be inserted, you can pass it directly to executemany:
self.cursor.executemany("INSERT INTO blacklisted_ips (ip, source_id, date_created, date_modified) VALUES (%s, %s, %s, %s);", address_list)
(Note the lack of quotes and brackets around address_list.)
Related
sql = """INSERT INTO (Product_details) VALUES (%s, %s, %s, %s, %s, %s)"""
val = [name, Spec ,Ratings ,Delivery ,Discount ,Price ] # list of data into list
for values in val: #loping the variables in the list and adding it to database
engine.execute(sql, values)
It looks like you're using Python - Try ? instead of %s - sometimes the parameter marker is not what you would expect it to be so do check which one you need to use for the language you're embedding the SQL in
I am attempting to write into MySQL Table that was created using phpMyAdmin. I keep recieving the same error.
This is my code:
import pymysql
connection=pymysql.connect(user='root',password='', host='localhost',database='ProjDB')
cursor = connection.cursor()
sql = "INSERT INTO 'userdata' ('FName','LName','UserName','Pword') VALUES (%s, %s, %s, %s)"
cursor.execute(sql, ('XXXX','XXX','XXXX','XXXX'))
connection.commit()
The following line your code has some errors:
sql = "INSERT INTO 'userdata' ('FName','LName','UserName','Pword') VALUES (%s, %s, %s, %s)"
Your table name has single quote added to it. sql treats it as a string instead of table name.
The column names also are facing the same issue.
The values should be enclosed in single quotes as when formatting it via string the values are placed exactly as the string is without single quotes.
example to explain it more clearly:
your current code formats the VALUES as :
sql = "INSERT INTO 'userdata' ('FName','LName','UserName','Pword') VALUES ( XXXX, XXX, XXXX, XXXX)"
But your columns are of type varchar so they should be enclosed in single quotes.
change that query by removing the single quotes from table name and column names and add single quotes to the values.
sql = "INSERT INTO userdata (FName,LName,UserName,Pword) VALUES ('%s', '%s', '%s', '%s')"
cursor.execute(sql % ('XXXX','XXX','XXXX','XXXX'))
The Final formatted sql query will look like
INSERT INTO userdata (FName,LName,UserName,Pword) VALUES ('XXXX','XXX','XXXX','XXXX')
My CSV file contains data like this:
Date,portfolioValue,pID,FinancialInstrument
2018-03-27,4937.395022140785,1,Oil
2018-03-28,4937.395022140785,1,Oil
My insert execution code is as follows:
file = open(portfolio_file,'r')
csv_data = csv.reader(file, delimiter =',')
for row in df_header:
print(row)
#stmt = ("INSERT INTO PredictionData (Date, Open, Settle, High, Low, HorizonType, InstrumentName, PredictorType) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE Open=%s, Settle=%s, High=%s, Low=%s")
cursor.execute("INSERT INTO portfolioData(Date, portfolioValue, pID, FinancialInstrument) VALUES (DATE_FORMAT('%s','%%Y-%%m-%%d'), '%s', '%s', '%s') ON DUPLICATE KEY UPDATE portfolioValue ='%s'", row)
cnx.commit()
When I am running this I keep getting raise errorclass(errorvalue)
_mysql_exceptions.ProgrammingError: not enough arguments for format string
I have the same number of columns and formatting the date properly.
Change the SQL text to reference the value that would have been inserted (if the insert had succeeded), using the special VALUES() function, like this
ON DUPLICATE KEY UPDATE portfolioValue = VALUES(portfolioValue)
then there's no need to pass an extra second copy of the value
like #pault said, you need 5 items (because of the ON DUPLICATE KEY UPDATE portfolioValue ='%s' towards the end).
Just make a copy of your portfolioValue as the 5th item, for each row.
I'm working on a DB and I'm having trouble when using pymysql to INSERT some values
cur.execute("""INSERT INTO orders (name, size, type, is_done) VALUES (%s, %s, %s, %s)"""
% (name, size, type, is_done))
Where name, size and type are strings and is_done is a bool
It gives me the typical error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near, so I suppose the problem is a ', but how can I solve it?
Edit
I should also add that the name value is retrieved from a MySQL DB
The current accepted solution has a SQL injection vulnerability. You are not supposed to format the string with the % operator - just pass the tuple of arguments as a second argument, and the library will deal with the rest.
cur.execute("INSERT INTO orders (name, size, type, is_done) VALUES (%s, %s, %s, %s)",
(name, size, type, is_done))
Also see this answer and pymysql documentation.
I have found the problem, which was that instead of
cur.execute("""INSERT INTO orders (name, size, type, is_done)
VALUES (%s, %s, %s, %s)"""
% (name, size, type, is_done))
I should have done
cur.execute("""INSERT INTO orders (name, size, type, is_done)
VALUES ("%s", "%s", "%s", "%s")"""
% (name, size, type, is_done))
if you don't input value for id. You have an error. Try this query.
cur.execute("insert into orders values(%s, %s, %s, %s, %s)", (None, name, size, type, is_done))
"%s" and "None" for id column. This query running my code.
Note: Don't forget commit()
This might be a rather silly question but what am I doing wrong here? It creates the table but the INSERT INTO doesn't work, I guess I'm doing something wrong with the placeholders?
conn = psycopg2.connect("dbname=postgres user=postgres")
cur = conn.cursor()
escaped_name = "TOUR_2"
cur.execute('CREATE TABLE %s(id serial PRIMARY KEY, day date, elapsed_time varchar, net_time varchar, length float, average_speed float, geometry GEOMETRY);' % escaped_name)
cur.execute('INSERT INTO %s (day,elapsed_time, net_time, length, average_speed, geometry) VALUES (%s, %s, %s, %s, %s, %s)', (escaped_name, day ,time_length, time_length_net, length_km, avg_speed, myLine_ppy))
conn.commit()
cur.close()
conn.close()
The INSERT INTO call doesn't work, it gives me
cur.execute('INSERT INTO %s (day,elapsed_time, net_time, length, average_speed,
geometry) VALUES (%s, %s, %s, %s, %s, %s)'% (escaped_name, day ,time_length,
time_length_net, length_km, avg_speed, myLine_ppy))
psycopg2.ProgrammingError: syntax error at or near ":"
LINE 1: ...h, average_speed, geometry) VALUES (2013/09/01 , 2:56:59, 02...
Can someone help me on this one? Thanks a bunch!
You are using Python string formatting and this is a Very Bad Idea (TM). Think SQL-injection. The right way to do it is to use bound variables:
cur.execute('INSERT INTO %s (day, elapsed_time, net_time, length, average_speed, geometry) VALUES (%s, %s, %s, %s, %s, %s)', (escaped_name, day, time_length, time_length_net, length_km, avg_speed, myLine_ppy))
where the tuple of parameters is given as second argument to execute(). Also you don't need to escape any value, psycopg2 will do the escaping for you. In this particular case is also suggested to not pass the table name in a variable (escaped_name) but to embed it in the query string: psycopg2 doesn't know how to quote table and column names, only values.
See psycopg2 documentation:
https://www.psycopg.org/docs/usage.html#passing-parameters-to-sql-queries
If you want to programmatically generate the SQL statement, the customary way is to use Python formatting for the statement and variable binding for the arguments. For example, if you have the table name in escaped_name you can do:
query = "INSERT INTO %s (col1, ...) VALUES (%%s, ...)" % escaped_name
curs.execute(query, args_tuple)
Obviously, to use placeholders in your query you need to quote any % that introduce a bound argument in the first format.
Note that this is safe if and only if escaped_name is generated by your code ignoring any external input (for example a table base name and a counter) but it is at risk of SQL injection if you use data provided by the user.
To expand on #Matt's answer, placeholders do not work for identifiers like table names because the name will be quoted as a string value and result in invalid syntax.
If you want to generate such a query dynamically, you can use the referred to pyscopg2.sql module:
from psycopg2.sql import Identifier, SQL
cur.execute(SQL("INSERT INTO {} VALUES (%s)").format(Identifier('my_table')), (10,))
As of psycopg2 v2.7 there is a supported way to do this: see the psycopg2.sql docs.