parameters are of unsupported type - python

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()

Related

Using LOCK to prevent serializable isolation issue in Redshift

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:

sqlite SELECT statement returns None

I have an issue returning a string from my database query.
First step was to create a database:
def create_database():
# database setup
try:
con = sqlite3.connect('db/mydb.db')
cur = con.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS user (id INTEGER NOT NULL PRIMARY KEY, balance REAL NOT NULL, text TEXT NOT NULL)')
con.commit()
con.close()
except Error as e:
print('Failed to setup database.\n' + e)
exit(1)
def get_connection():
try:
con = sqlite3.connect('db/mydb.db')
return con
except:
print('Unable to connect to database. Please try again later.\n')
exit(1)
My second step was creating a user and add him with INSERT to my database:
def create_user(user_id : int):
balance = 0.0; # base unit = USD
text = create_text()
# connect to database
con = get_connection()
cur = con.cursor()
cur.execute('INSERT INTO user (id, balance, text) VALUES (?, ?, ?)', (user_id, balance, text))
database = cur.execute('SELECT * FROM user').fetchone()
print(database)
con.commit()
con.close()
def create_text():
# do some stuff which creates my text
# the text is something like 'LNURL...'
return text
This is how the result of my database query looks like:
(393120847059091456, 0.0, 'LNURL1DP68GURN8GHJ7URP09JX7MTPDCHXGEF0D3H82UNVWQHKZURF9AMRZTMVDE6HYMP0XGMQA9V7RT')
If I try to query this database for my text it returns nothing/None. My print(text) just produces an empty new line.
def get_text(user_id : int):
# connect to database
con = get_connection()
cur = con.cursor()
cur.execute('SELECT text FROM user WHERE id=?', (user_id,))
text = cur.fetchone()
con.commit()
con.close()
print(text)
return text
I think my sqlite database used 32bit int values by default. So forcing it to use 64 bit when creating the table fixed my issue:
cur.execute('CREATE TABLE IF NOT EXISTS user (id INT8 PRIMARY KEY NOT NULL, balance REAL NOT NULL, text TEXT NOT NULL')
Than I can return my result of the query with this: return text[0]

Python - Sequence of interdependent SQL queries

I am running 3 consecutive and dependent SQL queries and I am wondering if my code could be more efficient. I had to create 3 separate cursors to execute my method. What can I do to make it more efficient?
What I am doing in that method is:
Insert a new contributor in my contributors table based on the values send on the form
Get the primary key of that new contribution which is it's contributor_id
Insert a new question on the questions table and the foreign key of that table is the contributor_id from the contributors table
I don't want to use an ORM such as SQLAlchemy.
conn = pymysql.connect(
host = 'localhost',
user = 'root',
passwd = 'xxx!',
db = 'xxx'
)
#app.route('/add_contributor',methods = ['POST', 'GET'])
def add_contributor():
name = request.form.get('contrib_name')
question = request.form.get('question')
sql_1 = "INSERT INTO contributors (name) VALUES (%s)"
sql_2 = "SELECT contributor_id from contributors WHERE name=(%s)"
sql_3 = "INSERT INTO questions (contributor_id, question_text) VALUES (%s, %s)"
cursor = conn.cursor()
cursor.execute(sql_1, name)
cursor.fetchall()
conn.commit()
cursor_2 = conn.cursor()
cursor_2.execute(sql_2, name)
contrib_val = cursor_2.fetchall()
contrib_id = contrib_val[0][0]
cursor_3 = conn.cursor()
cursor_3.execute(sql_3, (contrib_id,question))
cursor_3.fetchall()
conn.commit()

Create table and insert two records SQL using python

I'm trying to create a table on a tempdb database on a local server KHBW001 using MSSQL. My code is:
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=KHBW001;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
cursor.executemany(
"CREATE TABLE tempdb.dbo.NewTestPyTable(Symbol varchar(15), Shares integer, Price double)") # creates new table
cursor.executemany("""
INSERT INTO tempdb.dbo.NewTestPyTable (Symbol, Shares, Price)
VALUES
[('ETH',55,199.55),
('KHC',66,33.5)]
""") # insert two records into new table
connection.commit()
I'm getting the error:
"CREATE TABLE tempdb.dbo.NewTestPyTable(Symbol varchar(15), Shares
integer, Price double)") # creates new table
TypeError: function takes exactly 2 arguments (1 given)
I don't quite understand what I'm doing wrong. Please assist
Figured it out...
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=KHBW001;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
cursor.execute(
"CREATE TABLE NewTestPyTable(Symbol varchar(15), Shares integer, Price integer)") # creates new table
params = [('ETH', 55, 199),
('KHC', 66, 33)]
# insert two records into new table
cursor.executemany(
"INSERT INTO tempdb.dbo.NewTestPyTable (Symbol, Shares, Price) VALUES (?, ?, ?)", params)
connection.commit()
i think first of all the problem is in table creation
here is the documentation how to create it correctly
https://www.w3schools.com/sql/sql_create_table.asp
type of data in SQL
https://www.journaldev.com/16774/sql-data-types
further it seems to me
you also need to use the money type for the price.
that's how i would do:
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=KHBW001;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
cursor.executemany(
"CREATE TABLE tempdb.dbo.NewTestPyTable(Symbol varchar(15), Shares int, Price money)") # creates new table
cursor.executemany("""
INSERT INTO tempdb.dbo.NewTestPyTable (Symbol, Shares, Price)
VALUES
('ETH',55,199.55),
('KHC',66,33.5);
""") # insert two records into new table
connection.commit()

select multiple columns using SQLite3 in Python

I have a list that contains the name of columns I want to retrieve from a table in the database.
My question is how to make the cursor select columns specified in the list. Do I have to convert nameList to a string variable before include it in the select statement? Thanks
nameList = ['A','B','C','D',...]
with sqlite3.connect(db_fileName) as conn:
cursor = conn.cursor()
cursor.execute("""
select * from table
""")
As long as you can be sure your input is sanitized -- to avoid SQL injection attack -- you can do:
...
qry = "select {} from table;"
qry.format( ','.join(nameList) )
cursor.execute(qry)
If you're on a really old version of Python do instead:
...
qry = "select %s from table;"
qry % ','.join(nameList)
cursor.execute(qry)
nameList = ["'A(pct)'",'B','C','D',...]
with sqlite3.connect(db_fileName) as conn:
cursor = conn.cursor()
cursor.execute("""
select {} from table
""".format(", ".join(nameList)))

Categories

Resources