I have a Python script that selects from a customer table then insert it into another table.
# coding: utf-8
import psycopg2
from psycopg2 import sql
from provider import post
from datetime import datetime
from uuid import uuid4
from utils import get_env
import constants
from utils import get_env, measure_runtime, raise_message, pprint, retry
from error_report import report, get_logger
db_url = get_env('conn_redshift')
conn = psycopg2.connect(db_url)
cur = conn.cursor()
#retry()
#raise_message("Unable to insert tuple to stripe customers")
def insert_tuple(cur, account, dictionary):
cur.execute(
begin;
lock {0}.customers;
sql.SQL("""
SELECT id, created_at FROM {0}.customers WHERE stripe_id = (%s);
""").format(sql.Identifier(account)), (dictionary['id'], ))
conn.commit()
customers = cur.fetchone()
print(f" > update customers {dictionary['id']}")
if customers and len(customers) == 2:
(id, created_at) = customers
else:
id = str(uuid4())
created_at = datetime.now().isoformat()
cur.execute(
"""
INSERT INTO stage_customers (
stripe_id,
name_1,
name_2,
address,
postcode,
city,
country_id,
updated_at,
created_at,
id
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""",
(dictionary['id'],
dictionary['name_1'], dictionary['name_2'], dictionary['address'],
dictionary['postcode'], dictionary['city'], dictionary['country_id'],
dictionary['updated_at'], created_at, id))
conn.commit()
#raise_message("Unable to import customers")
def import_customers(account, customers):
if account != constants.PUBLIC_STRIPE_CH and account != constants.PUBLIC_STRIPE_DE:
raise Exception('Unknown account -> ' + account)
if customers:
#db_url = get_env('conn_redshift')
#conn = psycopg2.connect(db_url)
#cur = conn.cursor()
print(f"{account} customers import: start # {datetime.now()}")
cur.execute(
sql.SQL("""
CREATE temp TABLE stage_customers (LIKE {0}.customers)
""")
.format(sql.Identifier(account))
)
conn.commit()
for customer in customers:
insert_tuple(cur, account, customers)
cur.execute(
sql.SQL("""
DELETE FROM {0}.customers WHERE {0}.customers.stripe_id IN (SELECT stripe_id FROM stage_customers);
""")
.format(sql.Identifier(account))
)
conn.commit()
cur.execute(
sql.SQL("""
INSERT INTO {0}.customers SELECT * FROM stage_customers;
""")
.format(sql.Identifier(account))
)
conn.commit()
cur.execute(
sql.SQL("""
DROP TABLE stage_customers;
""")
.format(sql.Identifier(account))
)
conn.commit()
print(f"{account} contact import: finished # {datetime.now()}")
#measure_runtime
##report(get_logger(channel="#dwh", app_name="Stripe Customers"))
def main():
ch_stripe_customers = post(constants.PUBLIC_STRIPE_CH, "/contact/search",
constants.PAYLOAD)
de_stripe_customers = post(constants.PUBLIC_STRIPE_DE, "/contact/search",
constants.PAYLOAD)
import_customers(constants.PUBLIC_STRIPE_CH, ch_stripe_customers)
import_customers(constants.PUBLIC_STRIPE_DE, de_stripe_customers)
if __name__ == "__main__":
main()
cur.close()
conn.close()
While running the Python script above, I receive the error:
Serializable isolation violation on table - 20123891, transactions forming the cycle are: 282075744, 238073135
Upon doing some research, Redshift recommends using LOCK to prevent this issue.
Could you please give an example how I can use the LOCK command in this Python script?
Or does psycopg2 probably provide a functionality to prevent this issue?
---Update---
If I try
BEGIN;
LOCK customers;
def insert_tuple(cur, account, dictionary):
cur.execute(
sql.SQL("""
SELECT id, created_at FROM {0}.customers WHERE customer_id = (%s);
""").format(sql.Identifier(account)), (dictionary['id'], ))
I got the error:
begin;
^
SyntaxError: invalid syntax
Update:
Related
I want to delete all rows in my table where the date is before or the same day as today, to update reservations in a hotel database.
dat_danas = datetime.datetime.today().date()
dat_danas.strftime("%d-%M-%Y")
conn = sqlite3.connect("rezervacije.db")
cursor = conn.cursor()
query = "DELETE FROM infoGosti WHERE DATE(odl_fld) <= ?"
cursor.execute(query, dat_danas,)
conn.commit()
Try something like this example:
import sqlite3, datetime
""" creating connection & table """
db = sqlite3.connect(':memory:') # creates db in Memory
cursor = db.cursor()
cursor.execute('''CREATE TABLE store (id INTEGER PRIMARY KEY, name TEXT, validity DATE)''')
db.commit()
""" populating data """
stores = [
['Stock 1', '12.10.2021'],
['Stock 2', '17.04.2022'],
['Stock 3', '27.11.2022'],
['Stock 4', '23.09.2022'],
]
cursor.executemany('''INSERT INTO store (name, validity) VALUES (?,?)''', stores)
db.commit()
""" queries """
today = datetime.date.today().strftime('%d.%m.%Y')
cursor.execute(""" SELECT * FROM store """) # result before deletion
db.commit()
res = cursor.fetchall()
query = """ DELETE FROM store WHERE validity < ? """
cursor.execute(query, (today,))
cursor.execute(""" SELECT * FROM store """) # result after deletion
db.commit()
res = cursor.fetchall()
import mysql.connector
def add_features_to_db(stockname, timeframe, date, feature):
try:
conn = mysql.connector.connect(
user='root', password='', host='localhost', database='fx003')
cursor = conn.cursor()
dbtable = stockname + timeframe
mySql_insert_query = """INSERT INTO `%s` (date, trend) VALUES ( `%s`, `%s` )"""
record = (dbtable, date, feature)
cursor.execute(mySql_insert_query, record)
conn.commit()
print("Record inserted successfully")
except mysql.connector.Error as error:
print("Failed to insert into MySQL table {}".format(error))
finally:
if conn.is_connected():
cursor.close()
conn.close()
print("MySQL connection is closed")
add_features_to_db("aud-cad", "_30mins", "2021-09-24 21:00:00", "Short")
I have the code above and giving me the below error:
Failed to insert into MySQL table 1146 (42S02): Table 'fx003.'aud-cad_30mins'' doesn't exist
aud-cad_30mins table does exist and an insert query like below doing its job:
mySql_insert_query = """INSERT INTO aud-cad_30mins (date, trend) VALUES ( "2021-09-24 21:00:00","Short" )"""
So when I try to use variables in the query, it gives the error. Why the table name getting unwanted quotes? Checked several tutorials but couldn't find a solution, any ideas?
The table name should be hardcoded in the query string instead of having it there as a placeholder %s, which is meant for the values to be inserted. So if you have the table name in the variable, you can replace it via format() before calling cursor.execute()
dbtable = stockname + timeframe
mySql_insert_query = """INSERT INTO {} (date, trend) VALUES ( %s, %s )""".format(dbtable)
see the examples in the docs
edit: as Bill mentioned in the comment, dont add the backticks around the %s placeholders.
I am trying to update a SQL Table given a users input I have the following code. The user can choose to enter in/change the below fields which are defaulted to the values in the SQL table. However when I run the code I get the following error message
mysql.connector.errors.ProgrammingError: Not enough parameters for the SQL statement
I have counted it many times and it seems like the %s match the passed parameters. Am I missing something?
user = User_name_body.get('1.0',END)
passw = Password_text.get('1.0',END)
first = First_name.get('1.0',END)
last = Last_name.get('1.0',END)
phone = Phone_number.get('1.0',END)
email = Email_address.get('1.0',END)
mycursor = mydb.cursor()
sql = "UPDATE t_users SET Email_address=%s, First_name=%s, Last_name=%s, Phone_Number=%s, Password=%s WHERE User_Name=%s VALUES(%s,%s,%s,%s,%s,%s)"
val = (email, first, last, phone, passw,user)
mycursor.execute(sql, val)
mydb.commit()
mydb.close()
UPDATE does not take VALUES, you should change your sql query line to look like this:
sql = "UPDATE t_users SET Email_address=%s, First_name=%s, Last_name=%s, Phone_Number=%s, Password=%s WHERE User_Name=%s"
Python throws an error because you are asking for 12 parameters and only providing 6.
Prepare your sql data like this:
sql = """ UPDATE t_users SET Email_address=%s, First_name=%s, Last_name=%s, Phone_Number=%s, Password=%s WHERE User_Name = %s """
val = (email, first, last, phone, passw, user)
mycursor.execute(sql, val)
or you can do it like this
sql = "UPDATE btms_users SET btms_users.user='%s', btms_users.secret='%s' , btms_users.first_name='%s', " \
"btms_users.second_name='%s', btms_users.email='%s', btms_users.mobile='%s' " \
"WHERE btms_users.id='%s'" % (user_name, user_secret, user_firstname, user_lastname,
user_email, user_phone, user_id)
mycursor.execute(sql)
and here is a full working example:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="test",
database="test"
)
mycursor = mydb.cursor()
sql = "UPDATE items SET name = %s WHERE id = %s"
val = ("Test", 1)
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "record(s) affected")
I am trying to update a mysql table with variable names. Below is the code that is not working for me:
import mysql.connector
conn= mysql.connector.connect(
host=host,
user=user,
passwd=password,
database=database
)
cur = conn.cursor()
cur.execute("update player_list set country = '%s', region = '%s',name = '%s' where id = %s "
% (country, region,name, id))
Running the "cur execute" line returns the following error:
mysql.connector.errors.InternalError: Unread result found
The ID column is an integer if it has any importance.
I don't see any code here how you've created your cursor, but looks like you need to specify buffered mode for your sql class to read.
Please, refer to official documentation and change your code to use buffer=True while creating your cursor and use it afterwards.
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorbuffered.html
Try
with conn.cursor() as cur:
sql = "update player_list set country = '%s', region = '%s',name = '%s' where id = %s" % (country, region,name, id)
cur.execute(sql)
conn.commit()
and add buffered = True into your conn like
connection = mysql.connector.connect([...], buffered = True)
I have a simple registration form which creates a new record in "Students" table:
cur = con.cursor()
query = "INSERT INTO students (Name, Address, Major, Phone, Email, Password) values (%s, %s, %s, %s, %s, %s)"
args = [name, address, major,phone, email, password]
cur.execute(query, args)
con.commit()
The column Id is auto-incremented, so in order to get the last Id, I select Max
query = "SELECT MAX(Id) FROM students;"
cur.execute(query)
id = cur.fetchone()[0]
It works in my little homework-project, but how would it be done in a heavy-loaded project, where there is a possibility of something being created before the select statement?
Use lastrowid attribute:
...
cur.execute(query, args)
id = cur.lastrowid