Using insert query in python for postgresql - python

I want to insert values to a database using python, but it's failed. This is my code:
try:
cur.execute("""INSERT INTO tb_distance (objek1, objek2, distance) VALUES ('%s','%s','%d')""", (data[i].jenis, data[k].jenis, distance))
conn.commit()
except:
conn.rollback()
print 'cannot insert into database'

Thank you, I fixed my problem, I replace (,) to (%) before list of values. This is my code and run well:
cur.execute("""INSERT INTO tb_distance (objek1, objek2, distance) VALUES ('%s','%s','%f')""" % (data[i].jenis, data[k].jenis, distance))

Remove quotes around the placeholders ('%s' -> %s, '%d' -> %d):
cur.execute(
"INSERT INTO tb_distance (objek1, objek2, distance) VALUES (%s, %s, %d)",
(data[i].jenis, data[k].jenis, distance)
)

Related

Error importing CSV With Python to MYSQL - TypeError: not enough arguments for format string

I'm facing a problem trying to insert a CSV file with 800 records in the database. This gives me the following error: MySQLdb.ProgrammingError: not enough arguments for format string. I already checked and the exchanges and variables are correct, could you help me what would this problem be? Here is the code:
import MySQLdb
import csv
conn = MySQLdb.connect(host="127.0.0.1", user="root", password="", database="csm")
cursor = conn.cursor()
csv_data = csv.reader(open('teste2.csv'))
header = next(csv_data)
for row in csv_data:
print(row)
cursor.execute(
"INSERT INTO estoque1 (release, official, order, date, product, client, sales, sales, quant) VALUES (%s, %s, %s, %s, %s ,%s ,%s ,%s ,%s)", row)
conn.commit()
cursor.close()
I'm facing this error but idk how to solve this. Anyone have some tips about this how can i solve?
Follow the image:
Because you're passing the array as an argument while the execute() function expects all the elements of the array as a single argument.
You should be able to pass the array like this:
cursor.execute(
"INSERT INTO estoque1 (release, official, order, date, product, client, sales, sales, quant) VALUES (%s, %s, %s, %s, %s ,%s ,%s ,%s ,%s)",
*row
)
Note the asterisk.
The Problem is that you only pass one parameter (the row list) to the 9 placeholders in your string. To fix that you need either convert the list to a tuple, use the "*" operator to unpack the list or pass all the values of the list individually.
Use the * operator to unpack:
row = [1, 2, 3, 4]
"%s %s %s %s" % (*row,)
Use tuple:
row = [1, 2, 3, 4]
"%s %s %s %s" % tuple(row)
Or you list all parameters extra:
row = [1, 2, 3, 4]
"%s %s %s %s" % (row[0], row[1], row[2], row[3])

SQL why input string becomes 0?

I'm using python's psycopg2 to create a table and the insert SQL string look like this
create_table ='''CREATE TABLE Datetime_Response(
rid BIGINT NOT NULL,
qid BIGINT,
roid BIGINT,
rotext VARCHAR(20)
)'''
INSERT INTO Datetime_Response (rid, qid, roid, rotext)
VALUES
(13020638659, 711799502, 4681912759, 07/21/2021)
But the output is weird. All the datetime string becomes 0. I tried both VARCHAR and TEST in the column rotext. They all show 0. I don't know what goes wrong.
(13020638659, 711799502, 4681912759, '0')
This is what the values looks like
values = list(entry.values())
print(values)
['13020638659', '711799502', '4681912759', '07/21/2021']
And this is what the insert syntax look like
values_str = "(%s)" % (', '.join( values ))
sql_string = "INSERT INTO %s (%s)\nVALUES\n %s" % (
table_name,
', '.join(columns),
values_str
)
print(sql_string)
INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext)
VALUES
(13020638659, 711799502, 4681912759, 07/21/2021)
Do it like this. Let the connector fill in the properly quoted values:
sql_string = "INSERT INTO %s (%s)\nVALUES (%s)" % (
table_name,
','.join(columns),
','.join(['?']*len(values))
)
cur.execute( sql_string, values )
Because 7 divided by 21 divided by 2021 is close to zero. / is integer division in Python 2 if both operands are an integer. Quote your value: 07/21/2021
Your query is open to SQL injection attacks by malicious users of your script!
values = list(entry.values())
print(values)
['13020638659', '711799502', '4681912759', '07/21/2021']
values_str = "(%s)" % (', '.join( values ))
sql_string = "INSERT INTO %s (%s)\nVALUES\n %s" % (
table_name,
', '.join(columns),
values_str
)
print(sql_string)
When using your string values to format your string, you will end up with:
INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext)
VALUES (13020638659, 711799502, 4681912759, 07/21/2021)
which does not contain any quotation marks. Use prepared statements to avoid problems caused by wrong types and to stop hackers from misusing your application/database.
If, for whatever reason, you cannot use prepared statements, make sure the string ends up as string in your final statement:
values = ['13020638659', '711799502', '4681912759', "'07/21/2021'"]
or INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext) VALUES (%s, %s, %s, '%s)

Getting String Index Out of Range When Inserting to Postgresql table

I'm new to python, programming in general, and trying to read a .dat file and insert the data into a postgres table.
I'm getting an error and I've googled but could not come up with a resolution. Hoping someone can point me to the right direction.
Ratings table:
UserID int
MovieID int
Rating float
Ratings.dat:
1::122::5::838985046
1::185::5::838983525
Below is my code:
import psycopg2
ratingsfile = open('ml-10M100K/ratings.dat', 'r')
for line in ratingsfile:
items = line.split('::')
for values in items:
curr.execute("INSERT INTO Ratings(UserID, MovieID, Rating)
VALUES (%s, %s, %s)", values)
conn.commit()
ratingsfile.close()
Error:
curr.execute("INSERT INTO Ratings(UserID, MovieID, Rating)
VALUES (%s, %s, %s)", values)
IndexError: string index out of range
You do not need to iterate through items. Instead you can assign the 3 %s variables as items[index] as follows:
import psycopg2
ratingsfile = open('ml-10M100K/ratings.dat', 'r')
for line in ratingsfile:
items = line.split('::')
curr.execute("INSERT INTO Ratings(UserID, MovieID, Rating) VALUES (%s, %s, %s)" % (items[0], items[1], items[2]))
conn.commit()
ratingsfile.close()
This assumes that, for example in your example Ratings.dat, that UserID is 1 (items[0]), MovieID is 122 and 185 (items[1]), and Rating is 5 (items[2]). The 9 digit integers at the end of each row can be accessed with items[3]

How to use multiple Python Variables in an SQL Query

At the moment, I'm trying to use query a mySQL database with Python variables. I understand the convention for using variables in a query are as follows:
curr.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
However, the query I want to execute is as follows:
SELECT * FROM table1
WHERE City = (cityName)
AND AdmissionDate BETWEEN (startDate) AND (endDate)
I'm not sure how the variables would need to be formatted, whether they all need to be in the 1 tuple or I can format it as I would in a printf statement so I'm not sure which of the below would be correct:
curr.execute("SELECT * FROM table1
WHERE City = (%s)
AND AdmissionDate BETWEEN (%s) AND (%s)",(cityName, startDate, endDate))
curr.execute("SELECT * FROM table1
WHERE City = (%s)
AND AdmissionDate BETWEEN (%s) AND (%s)", (cityName), (startDate), (endDate))
Any tips would be greatly appreciated. Thanks in advance.

mixing placeholders, executemany, and table names

I can iterate through a python object with te following code, however I would like to be able to use placeholders for the schema and table name, normally I do this with {}.{} ad the .format() methods, but how do you combine the two?
cur.executemany("INSERT INTO schema.table_name (x,y,z) "
"values (%s, %s, %s)", top_sample)
Depends on which python you use you can try use f-string
schema = "schema"
table_name = "table_name"
cur.executemany(f"INSERT INTO {schema}.{table_name} (x,y,z) values (%s, %s, %s)", top_sample)
check PEP 498 -- Literal String Interpolation
another option is a simple format
cur.executemany("INSERT INTO {schema}.{table_name} (x,y,z) values (%s, %s, %s)".format(schema=schema, table_name=table_name), top_sample)
but I find the first option shorter and cleaner
I'm not sure what the issue is. You can very well use format like this:
cur.executemany("INSERT INTO {}.{} (x,y,z) values (%s, %s, %s)".format('hello', 'world'), top_sample)
cur.executemany(
"""INSERT INTO schema.{table_name} (x,y,z) values (%s, %s, %s)""".format(table_name=your_table_name),
top_sample
)
place your table name in place of your_table_name

Categories