Cannot code auto increment id in SQLite Flask - python

I have just created a new column, Id in DB Browser sqlite. I am not sure how am I suppose to code this portion in App.py. Should I use a id = request.form['id]?
App.py
#app.route('/addrec', methods=['POST', 'GET'])
def addrec():
if request.method == 'POST':
id =
use = session['user'].get("name")
ema = session['user'].get("preferred_username")
type = request.form['type']
uploadre = request.form['uploadre']
amt = request.form['amt']
description = request.form['description']
if request.form.get("price"):
price_checked = "Yes"
else:
price_checked = "No"
conn = sql.connect(db_path)
c = conn.cursor()
c.execute(
"INSERT INTO SubmitClaim VALUES (?,?,?,?,?,?,?,?)", (id, use,ema, type, uploadre, amt,price_checked, description))
conn.commit()
c.execute("SELECT * FROM SubmitClaim")
print(c.fetchall())
conn.close()
return render_template('base.html', user=session["user"], version=msal.__version__)
This is my table in DB Browswer Sqlite
CREATE TABLE "SubmitClaim" (
"id" INTEGER,
"Name" TEXT NOT NULL,
"Email" TEXT NOT NULL,
"ClaimType" TEXT NOT NULL,
"UploadReceipt" TEXT NOT NULL,
"ClaimAmount" INTEGER NOT NULL,
"checkbox" TEXT NOT NULL,
"ClaimDescription" TEXT NOT NULL,
PRIMARY KEY("id")
)

Here's how you set up an integer primary key column in sqlite and then insert and select from it:
import sqlite3
conn = sqlite3.connect('test.db')
conn.execute('''
CREATE TABLE SubmitClaim (
Id INTEGER PRIMARY KEY NOT NULL,
Name NVARCHAR NOT NULL,
Email NVARCHAR NOT NULL,
ClaimType NVARCHAR NOT NULL,
UploadReceipt NVARCHAR NOT NULL,
ClaimAmount INTEGER NOT NULL,
Checkbox NVARCHAR NOT NULL,
ClaimDescription NVARCHAR NOT NULL
)
''')
conn.commit()
conn.execute("INSERT INTO SubmitClaim (Name, Email, ClaimType, UploadReceipt, ClaimAmount, Checkbox, ClaimDescription) VALUES ('Foo Bar', 'foo#bar.com', 'A', 'Blah', 10, 'Checked', 'Description goes here')")
conn.commit()
cursor = conn.execute('SELECT * FROM SubmitClaim')
for row in cursor:
print(row)
And here's a colab notebook demonstration: https://colab.research.google.com/drive/1OhV9lWSBxLpOv45bNKmtRx9H0j6BZ-S3?usp=sharing
So your code sample above becomes:
#app.route('/addrec', methods=['POST', 'GET'])
def addrec():
if request.method == 'POST':
use = session['user'].get("name")
ema = session['user'].get("preferred_username")
type = request.form['type']
uploadre = request.form['uploadre']
amt = request.form['amt']
description = request.form['description']
if request.form.get("price"):
price_checked = "Yes"
else:
price_checked = "No"
conn = sql.connect(db_path)
conn.execute('''
INSERT INTO SubmitClaim
(Name, Email, ClaimType, UploadReceipt, ClaimAmount, Checkbox, ClaimDescription)
VALUES (?,?,?,?,?,?,?)''',
(use, ema, type, uploadre, amt, price_checked, description))
conn.commit()
c = conn.execute("SELECT * FROM SubmitClaim")
print(c.fetchall())
conn.close()
return render_template('base.html', user=session["user"], version=msal.__version__)

Related

ON CONFLICT DO UPDATE syntax and EXCLUDED error on cursor.executemany

I have a simplified postgres (ver 13) table below with updated rows generated in python with psycopg2.
My question is when I update the price field in the rows, I can't complete the update because of the following errors of ON CONFLICT DO UPDATE. If I don't use ON CONFLICT DO UPDATE , I can update the chart but I would like ON CONFLICT DO UPDATE because it eliminates duplicate rows.
With ON CONFLICT DO UPDATE , I only need to update the fields "price" and "last_updated" but update only when the rows match the "id,item,original_price_date"
The following errors I get ON CONFLICT DO UPDATE :
Error : syntax error at or near "="
# update the prices within the existing data
df = pd.DataFrame(np.array([['5/3/2010', 'rock', 15],
['4/15/2010', 'paper', 11],
['2/3/2015', 'scissor', 13]]),
columns = ['original_price_date', 'item', 'price'])
tuples_for_dB = [tuple(x) for x in df.to_numpy()]
sql_script = '''INSERT INTO ''' + TABLE_ + ''' (
original_price_date, item, price, created_date, last_updated)
VALUES (%s, %s, %s, transaction_timestamp(), transaction_timestamp())
ON CONFLICT (id, item, original_price_date)
DO UPDATE SET (price, last_updated = EXCLUDED.price, EXCLUDED.transaction_timestamp());'''
Error : relation "price_data" does not exist
sql_script = '''INSERT INTO ''' + TABLE_ + ''' (
original_price_date, item, price, created_date, last_updated)
VALUES (%s, %s, %s, transaction_timestamp(), transaction_timestamp())
ON CONFLICT (id, item, original_price_date)
DO UPDATE SET (price, last_updated) = (EXCLUDED.price, EXCLUDED.transaction_timestamp());'''
My original creation of the data :
# postGRESQL connection details
DATABASE_INITIAL_ = 'postgres'
DATABASE_ = 'data'
TABLE_ = 'price_data'
USER_ = 'postgres'
SERVERNAME_ = 'localhost'
PASSWORD_ = password_
HOST_ = '127.0.0.1'
PORT_ = '5432'
#establishing the connection
conn = psycopg2.connect(database = DATABASE_,
user = USER_,
password = PASSWORD_,
host = HOST_,
port = PORT_);
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT);
conn.autocommit = True
# Creating a cursor object using the cursor() method
cursor = conn.cursor()
sql = "SELECT 1 FROM pg_catalog.pg_database WHERE datname = " + "'" + DATABASE_ + "'"
cursor.execute(sql)
# If dB does not exist create the dB
exists = cursor.fetchone()
print(exists)
if not exists:
print('does not exist')
#Preparing query to create a database
sql = '''CREATE database '''+DATABASE_;
#Creating a database
cursor.execute(sql)
# Creating the table
sql = '''CREATE TABLE IF NOT EXISTS ''' + TABLE_ + ''' (
id SERIAL PRIMARY KEY,
original_price_date DATE NOT NULL,
item TEXT NOT NULL,
price NUMERIC NULL DEFAULT NULL,
created_date TIMESTAMPTZ NULL DEFAULT TRANSACTION_TIMESTAMP(),
last_updated TIMESTAMPTZ NULL DEFAULT TRANSACTION_TIMESTAMP());'''
cursor.execute(sql)
# update the table with data
df = pd.DataFrame(np.array([['5/3/2010', 'rock', 0.9],
['4/15/2010', 'paper', 6.5],
['2/3/2015', 'scissor', 3.9],
['3/23/2017', 'ball', 1.1],
['4/7/2013', 'tire', 5.4]]),
columns = ['original_price_date', 'item', 'price'])
tuples_for_dB = [tuple(x) for x in df.to_numpy()]
sql_script = '''INSERT INTO ''' + TABLE_ + ''' (
original_price_date, item, price, created_date, last_updated)
VALUES (%s, %s, %s, transaction_timestamp(), transaction_timestamp());'''
try:
cursor.executemany(sql_script, tuples_for_dB);
success = True
except psycopg2.Error as e:
error = e.pgcode
print(f'Error : {e.args[0]}')
success = False
if success:
print(f'\nData inserted successfully........')
print(f'Table INSERT sql commit comment :\n"{sql_script}"\n')
elif success == False:
print(f'\nData NOT inserted successfully XXXXXX')
# Preparing query to drop a table
sql = '''DROP TABLE IF EXISTS ''' + TABLE_ + ";"
# Creating the table
cursor.execute(sql)
conn.close()
I added a constraint row (CONSTRAINT com UNIQUE (original_price_date,item))) where I created the table.
sql = '''CREATE TABLE IF NOT EXISTS ''' + TABLE_ + ''' (
id SERIAL PRIMARY KEY,
original_price_date DATE NOT NULL,
item TEXT NOT NULL,
price NUMERIC NULL DEFAULT NULL,
created_date TIMESTAMPTZ NULL DEFAULT TRANSACTION_TIMESTAMP(),
last_updated TIMESTAMPTZ NULL DEFAULT TRANSACTION_TIMESTAMP(),
CONSTRAINT com UNIQUE (original_price_date,item));'''
Then I could insert the data NOT creating duplicate rows of (original_price_date,item) by the following statement.
sql = '''INSERT INTO ''' + TABLE_ + '''(original_price_date, item, price)
VALUES (%s, %s, %s)
ON CONFLICT (original_price_date, item)
DO UPDATE
SET (price, last_updated) = (EXCLUDED.price,TRANSACTION_TIMESTAMP());'''

Bad format for date in Mysql by mysqlconnector

I created a table with mysql.connector like this:
CREATE TABLE %s (ID int NOT NULL AUTO_INCREMENT,
date VARCHAR(200) NOT NULL default'{}',
s_time VARCHAR(30) NOT NULL default'{}',
shukkin VARCHAR(30) NOT NULL default'{}',
taikin VARCHAR(30) NOT NULL default'{}',
t_time VARCHAR(30) NOT NULL default'{}',
shucchou VARCHAR(30) NOT NULL default'{}',
shucchou_time VARCHAR(30) NOT NULL default'{}',
shucchou_kaeri_time VARCHAR(30) NOT NULL default'{}',
PRIMARY KEY (ID))" %val_s
And I'm trying to insert there and date now with this code block
now2 = datetime.datetime.now()
now = now2.strftime("%m/%d/%Y")
but when I insert to date VARCHAR(200) it becomes something like this
0.000742942050520059
And I dont know where is a problem... I tried inserting directly like this 06/04/2019 but when I selected * from table it shows same number as above.
Can someone please tell me where is a problem?
now2 = datetime.datetime.now()
now = now2.strftime("%m/%d/%Y")
now_t = now2.strftime("%H:%M:%S")
# For showing image of above settings --OPTION--
# show the output image
#cv2.imshow("Image", image)
#cv2.waitKey(0)
# SQL for "shukkin"
try:
connection = mysql.connector.connect(host='localhost', database='ninsho', user='root', password='0308', unix_socket="/var/run/mysqld/mysqld.sock")
cursor = connection.cursor()
valler = name.copy()
val_s = valler.replace(" ", "")
stmt = "SHOW TABLES LIKE '%s'" %val_s
cursor.execute(stmt)
result = cursor.fetchone()
if result:
print("je")
dates = now
# print ("date=", dates, "now=", now)
# Check if there is record from today ("shukkin")
query = "SELECT date FROM %s WHERE date = %s AND shukkin = %s" % (val_s, dates, str("'"+name+"'"))
try:
# print("rorororo")
cursor.execute(query)
myresult = cursor.fetchall()
# print(myresult)
for x in myresult:
#print("ttt")
a = x[0]
print(a)
if a == now:
# If there is record from today - Update it
names.set(name + "さん" + "\n" + "エラー:もう登録済")
memo.set("今日はすでに出勤を登録しました")
# If there is no record from today - Create it
else:
now2 = datetime.datetime.now()
now = now2.strftime("%m/%d/%Y")
val = name
val_s = val.replace(" ", "")
sql_insert_query = "INSERT INTO `%s`(`date`, `s_time`, `shukkin`) VALUES (%s, %s, %s)" % (val_s, now, now_t, name)
cursor = connection.cursor()
result = cursor.execute(sql_insert_query)
connection.commit()
#print ("Record inserted successfully into table")
except:
print("except")
now2 = datetime.datetime.now()
now3 = now2.strftime("%m/%d/%Y")
val = name
val_s = val.replace(" ", "")
sql_insert_query2 = "INSERT INTO `%s`(`date`, `s_time`, `shukkin`) VALUES (%s, %s, %s)" % (val_s, now3, str("'"+now_t+"'"), str("'"+name+"'"))
print(val_s, now3, now_t, name)
cursor = connection.cursor()
result = cursor.execute(sql_insert_query2)
print("except2")
connection.commit()
else:
print("nieje")
val = name
val_s = val.replace(" ", "")
query = "CREATE TABLE %s (ID int NOT NULL AUTO_INCREMENT, date VARCHAR(200) NOT NULL default'{}', s_time VARCHAR(30) NOT NULL default'{}', shukkin VARCHAR(30) NOT NULL default'{}', taikin VARCHAR(30) NOT NULL default'{}', t_time VARCHAR(30) NOT NULL default'{}', shucchou VARCHAR(30) NOT NULL default'{}', shucchou_time VARCHAR(30) NOT NULL default'{}', shucchou_kaeri_time VARCHAR(30) NOT NULL default'{}', PRIMARY KEY (ID))" %val_s
cursor.execute(query)
myresult = cursor.fetchall()
gettr()
except mysql.connector.Error as error :
connection.rollback() #rollback if any exception occured
#print("Failed inserting record into table {}".format(error))
finally:
if(connection.is_connected()):
cursor.close()
connection.close()
#print("MySQL connection is closed")

Copy data from one table to another sqlite3

So I have a database containing the products I will be holding, within this database I have a basket table where users can add items they would like to buy. For some reason, I am unable to take a selection within the view window and copy that data into my basket table.
Here is the function I have created for moving the data.
def Move():
if not tree.selection():
error = tkMessageBox.showerror("Error", "Cannot move nothing to basket")
else:
result = tkMessageBox.askquestion('CCOS', 'Do you want to add this to the basket?', icon="warning")
if result == 'yes':
curItem = tree.selection()
print(curItem)
contents = (tree.item(curItem))
selecteditem = contents['values']
Database()
cursor.execute("INSERT INTO `basket` (product_name, product_qty, product_price) VALUES(?, ?, ?)",
(str(PRODUCT_NAME.get()), int(PRODUCT_QTY.get()), int(PRODUCT_PRICE.get())))
conn.commit()
PRODUCT_ID.set("")
PRODUCT_NAME.set("")
PRODUCT_PRICE.set("")
PRODUCT_QTY.set("")
cursor.close()
conn.close()
Comment:
I have a range of different functions in my code, Database() is its own function that creates the database and cursor = conn.connect(). I am not getting an error, but when i run the function, no data is copied into the table.
When I call print(curItem), all that is outputted is : ('I002',)
Here is the database function:
def Database():
global conn, cursor
conn = sqlite3.connect("main_storage.db")
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS `admin` (admin_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username TEXT, password TEXT)")
cursor.execute("CREATE TABLE IF NOT EXISTS `product` (product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, product_name TEXT, product_qty TEXT, product_price TEXT)")
cursor.execute("CREATE TABLE IF NOT EXISTS `basket` (product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, product_name TEXT, product_qty TEXT, product_price TEXT)")
cursor.execute("SELECT * FROM `admin` WHERE `username` = 'admin' AND `password` = 'admin'")
if cursor.fetchone() is None:
cursor.execute("INSERT INTO `admin` (username, password) VALUES('admin', 'admin')")
conn.commit()

Python Iterate through list of dictionaries and save to db

Im new to python and trying to save raw post data in python into mysql.
I want to iterate over each element in the json that is posted and save all the data to DB.
json list of objects: (30 objects with each 11 columns)
[
{
"col1":7878,
"col2":"c004979d3969a86a8fdcda2f92eb39e3",
"col3":"b000yht23",
...
"col11":2
},
{
"col1":7878,
"col2":"c004979d3969a86a8fdcda2f92eb39e3",
"col3":"b000yht23"
...
"col11":43
},
#upto 30 objects
....
]
'json_test' table desc:
CREATE TABLE json_test (
`col1` varchar(250) NOT NULL,
`col2` varchar(250) NOT NULL,
`col3` varchar(250) NOT NULL,
`col4` varchar(250) NOT NULL,
`col5` varchar(250) NOT NULL,
`col6` varchar(250) NOT NULL,
`col7` varchar(250) NOT NULL,
`col8` varchar(250) NOT NULL,
`col9` varchar(250) NOT NULL,
`col10` varchar(250) NOT NULL,
`col11` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
UPDATED to save data to DB:
My py code looks like:
from flask import Flask, abort, request
import json
import pymysql
app = Flask(__name__)
#app.route('/foo', methods=['GET','POST'])
def foo():
jsonobject=request.json
if not jsonobject:
abort(400)
# load- converts JSON source text to a Python value
#readable_json=json.dumps(jsonobject)
#UPDATED with column_names
k=0
for i in jsonobject:
# Connect to the database
conn = pymysql.connect(host='10.20.3.4', port=3306, user='root', passwd='', db='python_db')
try:
with conn.cursor() as cursor:
column_names = ['col1','col2','col3',...'col11']
column_names_str = ', '.join(column_names)
binds_str = ', '.join('%s' for _ in range(len(column_names)))
sql=("INSERT INTO `json_test` ({column_names})" \
" VALUES({binds})"
.format(column_names=column_names_str,binds=binds_str))
for data_dict in jsonobject:
values = [data_dict[column_name]
for column_name in column_names]
cursor.execute(sql, values)
print("Insert successfull!")
#UPDATED
k+=1
conn.commit()
finally:
conn.close()
return "Insert successful"
#return json.dumps(jsonobject)
if __name__ == '__main__':
app.run(host='10.22.1.168',debug=True,port=7845)
UPDATED code result:
Only the last record seems to be inserting
Replace this mess
#UPDATED with column_names
k=0
for i in jsonobject:
# Connect to the database
conn = pymysql.connect(host='10.20.3.4', port=3306, user='root', passwd='', db='python_db')
try:
with conn.cursor() as cursor:
column_names = ['col1','col2','col3',...'col11']
column_names_str = ', '.join(column_names)
binds_str = ', '.join('%s' for _ in range(len(column_names)))
sql=("INSERT INTO `json_test` ({column_names})" \
" VALUES({binds})"
.format(column_names=column_names_str,binds=binds_str))
for data_dict in jsonobject:
values = [data_dict[column_name]
for column_name in column_names]
cursor.execute(sql, values)
print("Insert successfull!")
#UPDATED
k+=1
conn.commit()
finally:
conn.close()
return "Insert successful"
with
try:
with conn.cursor() as cursor:
columns_names = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6',
'col7', 'col8', 'col9', 'col10', 'col11']
columns_names_str = ', '.join(columns_names)
binds_str = ', '.join('%s' for _ in range(len(columns_names)))
for data_dict in jsonobject:
sql = ("INSERT INTO json_test ({columns_names}) "
"VALUES ({binds})"
.format(columns_names=columns_names_str,
binds=binds_str))
values = [data_dict[column_name]
for column_name in columns_names]
cursor.execute(sql, values)
print("Insert successfull!")
conn.commit()
finally:
conn.close()
Summation
k object is redundant,
also name i is unclear and makes me think like it is some kind of index when it is not: it is a dict object,
we don't need to create connection for each object from jsonobject because it is an expensive operation,
we don't need to create sql object on each iteration as well (it remains unchanged),
storing columns names in list/tuple will save us from writing them twice: in a query and in values extraction.
creating binds str
%s, %s, ...
dynamically based on number of columns saves us from typo when we've missed/added too many bind aliases
json.dumps does the opposite of what you claim; it converts a Python object into a string.
The result of request.json is already a Python datastructure. You don't need to do anything else with it.

Error 1318: Incorrect number of arguments for PROCEDURE ComicHub.sp_createUser; expected 3, got 4

I keep Error 1318 when running this code, I am supposed to have 4 arguments: username, email, password and location. It is picking up 4, but thinks it only wants 3 arguments. Code for Database and Python is below.
Python:
#app.route('/userSignUp',methods = ['POST'])
def userSignUp():
try:
#read values from signup form
_username = request.form['username']
_email = request.form['email']
_password = request.form['password']
_location = request.form['location']
#validate recieved values
if _username and _email and _password and _location:
cur = mysql.connection.cursor()
_hashed_password = generate_password_hash(_password)
cur.callproc('sp_createUser', (_username, _email, _hashed_password, _location))
data = cur.fetchall()
cur.close()
if len(data) is 0:
mysql.connection.commit()
return json.dumps({'success':'User created successfully!'})
else:
return json.dumps({'error':str(data[0])})
else:
return json.dumps({'html':'<span>Enter the required fields</span>'})
except Exception as e:
return json.dumps({'error':str(e)})
SQL:
# Create Database for ComicHub
CREATE DATABASE ComicHub;
# Create Table 'users' for ComicHub
CREATE TABLE `ComicHub`.`tbl_user` (
`user_id` BIGINT NULL AUTO_INCREMENT,
`user_username` VARCHAR(45) NULL,
`user_email` VARCHAR(45) NULL,
`user_password` VARCHAR(45) NULL,
`user_location` VARCHAR(66) NULL,
PRIMARY KEY (`user_id`)
);
# PROCEDURE for creating users from passed in data
USE `ComicHub`;
DELIMITER $$
CREATE PROCEDURE `sp_createUser` (
IN p_username VARCHAR(20),
IN p_email VARCHAR(20),
IN p_password VARCHAR(20),
IN P_location VARCHAR(20)
)
BEGIN
#check if user already exists
IF (select exists (select 1 from tbl_user where user_username = p_username) ) THEN
select 'Username Already Exists!';
ELSE
insert into tbl_user
(
user_username,
user_email,
user_password,
user_location
)
values
(
p_username,
p_email,
p_password,
p_location
);
END IF;
END$$
DELIMITER ;
Nevermind, fixed now, I realised I hadn't updated the database in MySQL Workbench. Stupid I know but its been a long day!

Categories