Problem to insert with psycopg2 with python - python

I'm trying to insert some rows, but this problema occurs:
TypeError: not all arguments converted during string formatting
sql code:
f"""insert into {table} ({insert}) VALUES ({formating}) ON CONFLICT ({', '.join(key)}) DO UPDATE SET ({insert}) = ({excluded})"""
sql translate:
insert into public.atend (cd_atendimento, cd_ori_ate, cd_paciente, op_type) VALUES (%s, %s, %s, %s) ON CONFLICT (cd_atendimento) DO UPDATE SET (cd_atendimento, cd_ori_ate, cd_paciente, op_type) = (EXCLUDED.cd_atendimento, EXCLUDED.cd_ori_ate, EXCLUDED.cd_paciente, EXCLUDED.op_type)

Related

Psycopg2, how to alias input values in sql query?

I need to update many rows with pyscopg based on input I receive. Input is list of tuples containing 3 elements.
input = [("Programing Langugae", "Python", "some path to img")]
_query_update = f"""UPDATE {TABLE} as t SET (category, name, img_path) = VALUES (%s, %s, %s) as t2 WHERE t.name = t2.name"""
db.cursor.executemany(_query_update, records)
db.connection.commit()
It throws me
psycopg2.errors.SyntaxError: syntax error at or near "("
LINE 1: ...ills as t SET (category, name, img_path) = VALUES ('framewor...
I need to use my middle value from the input in WHERE statement so I need to alias it somehow, because raw %s, %s, %s gives me nothing. How can I do it?

PostgreSQL INSERT ON CONFLICT and TKinter

I have problem with syntax within python/Tkinter when updating PostgreSQL table.
Syntax works for function code below without ON CONFLICT option:
def myclick_start():
# Create a database or connect to one
conn = psycopg2.connect(database="*",# hidden credentials here
host="*",
user="*",
password="*",
port="*")
# Create cursor
c = conn.cursor()
# Insert Into Database Table
thing1 = o_num.get()
thing2 = op_id.get()
thing3 = proc_name_cb.get()
# this works
c.execute('''INSERT INTO orders (order_id, op_id, status_id) VALUES (%s, %s, %s)''',
(thing1, thing2, thing3)
)
# Commit Changes
conn.commit()
# Close Connection
conn.close()
but not working when I want to UPDATE table ON CONFLICT of order_id value:
# but this is not working
c.execute('''INSERT INTO orders (order_id, op_id, status_id) VALUES (%s, %s, %s)''',
(thing1, thing2, thing3),
ON CONFLICT (order_id)
DO UPDATE SET op_id = EXCLUDED.op_id, status_id = EXCLUDED.status_id;
)
Resulted error:
File "E:\***.py", line 229
'''c.execute('''INSERT INTO orders (order_id, op_id, status_id) VALUES (%s, %s, %s)''',
^^^^^^
SyntaxError: invalid syntax
I've tried many syntax variants and kind of stuck with my error.
Appreciate your help.
If you take a closer look at the syntax highlight, you will notice that your ON CONFLICT ... isn't part of the SQL query (i.e. it's not part of the string that makes up the query).
Moving that part inside the string should solve the problem, like this
c.execute('''INSERT INTO orders (order_id, op_id, status_id) VALUES (%s, %s, %s)
ON CONFLICT (order_id)
DO UPDATE SET op_id = EXCLUDED.op_id, status_id = EXCLUDED.status_id;''',
(thing1, thing2, thing3)
)

Prevent to insert duplicates into table (python , sql)

I stepped over an problem while implementing a Database into my Python project.
I'm creating a new Table with the following Code:
mycursor = mydb.cursor()
sql = f"CREATE TABLE IF NOT EXISTS _{self.client_id} (tour_date DATE, tour_distance INT, tour_duration INT, tour_elevation_up INT, tour_elevation_down INT, tour_map_image TEXT, tour_name TEXT, tour_sport TEXT, tour_start_point TEXT, tour_type TEXT)"
mycursor.execute(sql)
mydb.commit()
I'm iterating over my Data and want to past it into the Table. But I won't want that if an entry already exists in the table it adds the same data again.
This is my code I currently have to Insert into my Table:
mycursor = mydb.cursor()
sql = f"INSERT INTO _{self.client_id} (tour_date, tour_distance, tour_duration, tour_elevation_up, tour_elevation_down, tour_map_image, tour_name, tour_sport, tour_start_point, tour_type) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) "
val = (TourDate, TourDistance, TourDuration, TourElevation_up, TourElevation_down, TourMap_image, TourName, TourSport, TourStart_point, TourType)
mycursor.execute(sql, val)
mydb.commit()
So my question is how can I check if a entry already exists in the Table and then avoiding creating a duplicate?
you can "select count() from your_table_name where client_id='current_id'
if count() return int that is greater than 0, you should not insert it into the databse.
First - avoid to use TEXT without it necessary
Second - create table with necessary indexes:
CREATE TABLE IF NOT EXISTS _{self.client_id} (
tour_date DATE,
tour_distance INT,
tour_duration INT,
tour_elevation_up INT,
tour_elevation_down INT,
tour_map_image TEXT,
tour_name VARCHAR(64) PRIMARY KEY,
tour_sport VARCHAR(64),
tour_start_point VARCHAR(64),
tour_type VARCHAR(64)
);
Third - use INSERT IGNORE ... statement for prevent duplicates

Anyway to Upsert database using PostgreSQL in Python

I want to upsert with least effort, for simplicity, i reduce columns, this not work:
sql = '''INSERT INTO temp.tickets
(id, created_at, updated_at, emails, status)
VALUES
(%s, %s, %s, %s, %s)
ON CONFLICT (id)
DO UPDATE SET ( emails, status) values (%s,%s)
'''
cursor = cm.cursor()
## cm is a custom module
cursor.execute(sql, (ticket['id'],
ticket['created_at'],
ticket['updated_at'],
ticket['emails'], ticket['status'], )
This code show Error:
return super(DictCursor, self).execute(query, vars)
IndexError: tuple index out of range
What I need to change in the cursor.execute() to work?
The Bellow code work but I like to use %s instead of type: email = excluded.email for each columns
sql = '''INSERT INTO temp.tickets
(id, created_at, updated_at, emails, status)
VALUES
(%s, %s, %s, %s, %s)
ON CONFLICT (id)
DO UPDATE SET emails = excluded.eamils, status = excluded.status
'''
cursor = cm.cursor()
# cm is a custom module
cursor.execute(sql, (ticket['id'],
ticket['created_at'],
ticket['updated_at'],
ticket['emails'], ticket['status'], )
There are two Relevant Questions link1, link2
I would try something like this:
sql = '''INSERT INTO temp.tickets
(id, created_at, updated_at, emails, status)
VALUES
(%s, %s, %s, %s, %s)
ON CONFLICT (id)
DO UPDATE SET ( emails, status) values (%s,%s)
'''
cursor = cm.cursor()
## cm is a custom module
cursor.execute(sql, (ticket['id'],
ticket['created_at'],
ticket['updated_at'],
ticket['emails'],
ticket['status'],
ticket['emails'],
ticket['status'] )
Thre number of %s must match the number of parameters.
When Postgres encounters a captured conflict it basically creates a record called EXCLUDED that contains the values you attempted to insert, You can refer to this record in DO UPDATE. Try the following:
INSERT INTO temp.tickets
(id, created_at, updated_at, emails, status)
VALUES
(%s, %s, %s, %s, %s)
ON CONFLICT (id)
DO UPDATE
SET emails = excluded.emails
, status = excluded.status
, updated_at = excluded.updated_at -- my assumption.
...
You will have to format is into the requirements of your source language.

Inserting mysql data from one table to another with python

I'm trying to insert data that's already in one mysql table into another, using python. The column names are the same in each table, and objkey is the distinguishing piece of data I have for the item that I'd like to use to tell mysql which columns to look at.
import MySQLdb
db = MySQLdb.connect(host='', user='', passwd='', db='')
cursor = db.cursor
sql = "INSERT INTO newtable (%s, %s, %s, %s) SELECT %s, %s, %s, %s FROM oldtable
WHERE %s;" % ((name, desig, data, num), name, desig, data, num, obj = repr(objkey))
cursor.execute(sql)
db.commit()
db.close()
It says I have a syntax error, but I'm not sure where since I'm pretty sure there should be parentheses around the field names the first time but not the second one. Anyone know what I'm doing wrong?
I'm not exactly sure what you are trying to do with the obj = repr(objkey) line, but python is thinking you are defining variables with this line, not setting sql syntax (if that is indeed your desire here).
sql = "INSERT INTO newtable (%s, %s, %s, %s) SELECT %s, %s, %s, %s FROM oldtable
WHERE %s;" % ((name, desig, data, num), name, desig, data, num, obj = repr(objkey))
should probably be changed to something like:
sql = "INSERT INTO newtable (%s, %s, %s, %s) SELECT %s, %s, %s, %s FROM oldtable
WHERE obj=%;" % ((name, desig, data, num), name, desig, data, num, repr(objkey))
But even then, you would need objkey defined somewhere as a python variable.
This answer may be way off, but you need to defined what you are expecting to achieve with obj = repr(objkey), in order to get more accurate answers.

Categories