After much trying on python3 (as of still new in this language), the line whereby cursor.execute will prevent the for loop to continue when condition met. However when I comment cursor.execute line, the looping able to continue until the end. How can I made it continue till the last result of the loop?
Objective to achieve: -
I am trying to filter a bunch of data from CFC_xxxx table, process and put it back into SENSOR_TREEHUGGERS table.
Line where the show stopper happened: -
cursor.execute(sqlInsert,
(xxGatewayId,qqqGatewayId,treeDiameter,temperature,recordTime,dateTime,treeHuggerID))
Python3 Code: -
import base64
import struct
import pymysql.cursors
import sys
import datetime
from contextlib import closing
connection = pymysql.connect(host='localhost',
user='xxx',
password='xxx',
db='xxx',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
with closing(connection.cursor()) as cursor:
sql = "SELECT * FROM CFC_xxxx"
cursor.execute(sql)
for row in cursor:
check = struct.unpack('>15x2f4B1L1x', base64.b64decode(row['Value']))
if check[6] > 20000 or check[6] < 10000:
continue
else:
xxGatewayId = int(row['Node_ID'])
qqqGatewayId = int(row['Gateway_ID'])
treeDiameter = int(check[0])
temperature = int(check[1])
recordTime = str(row['Timestamp'])
year = datetime.datetime.fromtimestamp(row['Timestamp']).strftime('%Y')
if check[2] == 0:
hours = '00'
else:
hours = str(check[2])
if check[3] == 0:
minute = '00'
else:
minute = str(check[3])
if check[4] < 10:
day = '0'+str(check[4])
else:
day = str(check[4])
if check[5] < 10:
month = '0'+str(check[5])
else:
month = str(check[5])
dateTime = str(year + '-' + month + '-' + day + ' ' + hours + ':' + minute + ':00')
treeHuggerID = int(check[6])
sqlInsert = "INSERT INTO SENSOR_TREEHUGGERS(`xx_Gateway_Id`,`qqq_Gateway_Id`,`treeDiameter`,`temperature`,`recordTime`,`dateTime`,`TreeHuggerId`) VALUES (%s,%s,%s,%s,%s,%s,%s)"
cursor.execute(sqlInsert, (xxGatewayId,qqqGatewayId,treeDiameter,temperature,recordTime,dateTime,treeHuggerID))
connection.commit()
Below is how I get my trouble solved. Using array to append all the processed data and use executemany to save them at once. In beforehand, have to modify mysql config max_allowed_packet = 500M
A pain but valuable lesson.
Answer: -
import base64
import struct
import pymysql.cursors
import sys
import datetime
from contextlib import closing
collectData = []
connection = pymysql.connect(host='localhost',
user='xxx',
password='xxx',
db='xxx',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
with closing(connection.cursor()) as cursor:
sql = "SELECT * FROM CFC_xxxx"
cursor.execute(sql)
for row in cursor:
check = struct.unpack('>15x2f4B1L1x', base64.b64decode(row['Value']))
if check[6] > 20000 or check[6] < 10000:
continue
else:
xxGatewayId = int(row['Node_ID'])
qqqGatewayId = int(row['Gateway_ID'])
treeDiameter = int(check[0])
temperature = int(check[1])
recordTime = str(row['Timestamp'])
year = datetime.datetime.fromtimestamp(row['Timestamp']).strftime('%Y')
if check[2] == 0:
hours = '00'
else:
hours = str(check[2])
if check[3] == 0:
minute = '00'
else:
minute = str(check[3])
if check[4] < 10:
day = '0'+str(check[4])
else:
day = str(check[4])
if check[5] < 10:
month = '0'+str(check[5])
else:
month = str(check[5])
dateTime = str(year + '-' + month + '-' + day + ' ' + hours + ':' + minute + ':00')
treeHuggerID = int(check[6])
collectData.append(xxGatewayId,qqqGatewayId,treeDiameter,temperature,recordTime,dateTime,treeHuggerID)
c1 = connection.cursor()
sqlInsert = "INSERT INTO SENSOR_TREEHUGGERS(`xx_Gateway_Id`,`qqq_Gateway_Id`,`treeDiameter`,`temperature`,`recordTime`,`dateTime`,`TreeHuggerId`) VALUES (%s,%s,%s,%s,%s,%s,%s)"
c1.executemany(sqlInsert, collectData)
connection.commit()
Related
conn = mysql.connector.connect(
host="localhost",
user="root",
passwd="12123123412"
database='newdb')
cur = conn.cursor()
xx_zz = self.screen.get_screen('end').ids["rgr"].text
ee_zz = self.screen.get_screen('end').ids["gfd"].text
qur = f"SELECT * FROM (%s) WHERE bedrooms = '(%s)' "
val = (xx_zz, ee_zz)
cur.execute(qur, val)
records = cur.fetchall()
I suggest that we use a function to create the query string using match-case. This will avoid any risk of SQL injection as we are not using the string provided by the front end.
You will need to modify and complete the option values and table names and decide whether there should be a default table name or no result if the option provided is not found.
Obviously this code has not been tested.
def makeQuery( option ):
match option:
case 'option1':
return f"SELECT * FROM table_name_1 WHERE bedrooms = '(%s)' "
case 'option2':
return f"SELECT * FROM table_name_2 WHERE bedrooms = '(%s)' "
case _:
return f"SELECT * FROM default_table_name WHERE bedrooms = '(%s)' "
conn = mysql.connector.connect(
host="localhost",
user="root",
passwd="12123123412"
database='newdb')
cur = conn.cursor()
xx_zz = self.screen.get_screen('end').ids["rgr"].text
ee_zz = self.screen.get_screen('end').ids["gfd"].text
qur = makeQuery(xx_zz )
val = ( ee_zz )
cur.execute(qur, val)
records = cur.fetchall()
In textInput (field) you use hint_text to show a placeholder in a text field(input).
def export_as_xls(self, request, queryset):
opts = self.model._meta
file_name = unidecode(opts.verbose_name)
sql_query = '''SELECT
COUNT(id) AS No_Of_Report,
vendor,
country_code,
SUM(new_code)*100/SUM(sent) AS 'failure_rate',
SUM(case when new_code =0 then 1 ELSE 0 end)*100/sum(sent) AS 'success_rate'
FROM sms_statistics
WHERE FROM_UNIXTIME(date) >= curdate() - interval 30 day
GROUP BY vendor, country_code
ORDER BY vendor DESC;'''
This is mysql query i used to call for the data in mysql schema
field_names = ('No of report', 'Vendor', 'Country Code', 'Failure Rate', 'Success Rate')
wb = Workbook()
ws = wb.active
ws.append(ExportExcelAction.generate_header(self, self.model, field_names))
with connection.cursor() as cursor:
cursor.execute(sql_query)
objects = list(cursor.fetchall())
for row in cursor.fetchall():
objects = list(row)
ws.append(objects)
print(ws.append(row))
ws = style_output_file(ws)
I think the issue is right here for not being able to export to excel. Im not be using the right method to export the file from action.py
response =
HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = f'attachment; filename={file_name}.xlsx'
wb.save(response)
return response
export_as_xls.short_description = "Reports of Past 30 days"
export_as_xls.acts_on_all = True
Blockquote
I believe this part is fine as i tried exporting an empty file and its working as expexted
def export_thirty_days(self, request, queryset):
opts = self.model._meta
file_name = "Sms Statistic Report"
sql_query = '''SELECT
COUNT(id) AS No_Of_Report,
vendor,
country_code,
SUM(new_code)*100/SUM(sent) AS 'failure_rate',
SUM(case when new_code =0 then 1 ELSE 0 end)*100/sum(sent) AS 'success_rate'
FROM sms_statistics
WHERE FROM_UNIXTIME(date) >= curdate() - interval 30 day
GROUP BY vendor, country_code
ORDER BY COUNT(id) DESC;'''
field_names = ('No of report', 'Vendor', 'Country Code', 'Failure Rate', 'Success Rate')
wb = Workbook()
ws = wb.active
ws.append(ExportExcelAction.generate_header(self, self.model, field_names))
with connection.cursor() as cursor:
cursor.execute(sql_query)
for row in cursor.fetchall():
l = list(row)
ws.append(l)
ws = style_output_file(ws)
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = f'attachment; filename={file_name}.xlsx'
wb.save(response)
return response
export_thirty_days.short_description = "Reports of Past 30 days"
export_thirty_days.acts_on_all = True
This is the solutions i've found to make it work
Is there a pattern for dealing with query params in a flask rest server? I know I can create a sql query word for word using string manipulation in python, but I find that to be ugly and error prone, I was wondering if there is a better way. Here's what I have:
param1 = request.args.get('param1', type = int)
param2 = request.args.get('param2', type = int)
if param1 is not None:
if param2 is not None:
cursor.execute("SELECT * FROM table WHERE p1 = %s AND p2 = %s", (str(param1), str(param2)))
else:
cursor.execute("SELECT * FROM table WHERE p1 = %s", (str(param1),))
else:
if param2 is not None:
cursor.execute("SELECT * FROM table WHERE p2 = %s", (str(param2),))
else:
cursor.execute("SELECT * FROM table")
It's easy to see the number of possible SQL statements is 2 to the number of parameters, which grows out of control... so, again, without using string manipulation to custom build the sql query, is there an idiom or pattern that is used to accomplish this in a more elegant way? Thanks.
Loop through your parameters.
params = []
for i in range(1, HoweverManyParamsYouNeed):
params.append(request.args.get('param' + str(i), type = int))
s = ""
for i in range(1, len(params)):
if params[ i ] is not None:
if not s:
s = "p" + str(i) + " = " + str(params[ i ])
else:
s = s + " AND p" + str(i) + " = " + str(params[ i ])
full = "SELECT * FROM table"
if s:
full = full + " WHERE " + s
cursor.execute(full)
You might need to correct this code, since I do not have a way to run it.
I suggest using ORM(https://en.wikipedia.org/wiki/Object-relational_mapping) instead of raw sql queries.
First you need install flask-sqlalchemy (https://flask-sqlalchemy.palletsprojects.com/)
Then define your model
class MyModel(db.Model):
id = db.Column(db.Integer, primary_key=True)
column1 = db.Column(db.Integer)
column2 = db.Column(db.Integer)
Let's say you have your filter lookup somewhere
allowed_filters = {"column1", "column2"}
Finally instead of cursor you can use SQLAlchemy's ORM to retrieve your filtered objects.
query = MyModel.query
for field, value in request.args.items():
if field in allowed_filters:
query = query.filter(getattr(MyModel, field) == value)
my_object_list = list(query.all())
If you really want to create your queries manually you can always iterate over args:
where_clause = ""
params = []
for field, value in request.args.items():
if field in allowed_filters:
if len(where_clause) > 0:
where_clause += " AND "
where_clause += "{} = %s".format(field)
params.append(value)
if len(where_clause) > 0:
cursor.execute("SELECT * FROM table WHERE {}".format(where_clause), tuple(params))
else:
cursor.execute("SELECT * FROM table")
Script working completely but its not entering any data.
Here my code:
from selenium import webdriver
from selenium.webdriver.support.ui import Select
import datetime
from login_credentials import *
from common_file import *
from selenium.webdriver.firefox.options import Options
from pyvirtualdisplay import Display
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
start_time = str(sdate)+" "+ str(stime)
end_time = str(edate)+" "+ str(etime)
options = Options()
options.headless = True
driver = webdriver.Firefox(executable_path='/usr/bin/geckodriver',options=options)
driver.get("https://www.goeventz.com/")
driver.find_element_by_xpath("//a[contains(text(),'Login')]").click()
print("going")
#driver.find_element_by_id("userlogin")
driver.find_element_by_id("user_email").send_keys(ge_email)
driver.find_element_by_id("password").send_keys(ge_pswd)
#driver.find_elements_by_class_name(".btn-login").click()
#driver.find_element_by_css_selector('btn-login').click()
driver.find_element_by_xpath("//button[#type='submit']").click()
driver.find_element_by_xpath("//a[contains(text(),'Create Event') and #id='headerbtn']").click()
driver.find_element_by_name("title").clear()
driver.find_element_by_name("title").send_keys(eventname)
driver.find_element_by_xpath("//a[contains(text(),'Enter Address')]").click()
driver.find_element_by_xpath("//input[contains(#name,'venue_name')]").send_keys(full_address)
driver.find_element_by_name("start_date_time").clear()
driver.find_element_by_name("start_date_time").send_keys(start_time)
driver.find_element_by_name("end_date_time").clear()
driver.find_element_by_name("end_date_time").send_keys(end_time)
driver.find_element_by_id("fileToUpload").send_keys("/var/www/html/crons/event_posting/manual/test.jpg")
driver.find_element_by_xpath("//div[contains(#class,'fr-element fr-view')]").send_keys('description')
select = Select(driver.find_element_by_name("booknow_button_value"))
select.select_by_value('Register')
select = Select(driver.find_element_by_name("category"))
select.select_by_value("Sports")
select = Select(driver.find_element_by_name("othercategory"))
select.select_by_value('Festival')
driver.find_element_by_name("support_mobile").send_keys(cont_number)
driver.find_element_by_name('support_email').send_keys(email_id)
driver.find_element_by_name("makeeventlive").click()
print("its complted")
and it running completly on server, this is output:
but its not entering any data as provided it just output it blank.
here the output im getting on browser:
output on browser
this is common_file:
from dbconnection import get_conn
from datetime import datetime
connection_object, cursor = get_conn()
json_0 = []
json12_in_list = []
json_12 = []
json34_in_list = []
json_34 = []
json5 = []
json678_in_list = []
json_678 = []
json9 = []
json10 = []
main_json = {}
event_details = ''
with open('event_details.txt', 'r') as f:
event_details = f.read()
event_id = int(event_details.split(',')[0])
site_id = int(event_details.split(',')[1])
site_name = str(event_details.split(',')[2])
#event_id =
sql = """SELECT * FROM articles2 WHERE id ='%d'""" %event_id
cursor.execute(sql)
data = cursor.fetchall()
for info in data:
eventid = info[0]
countryname = info[1]
eventname = info[2]
profileimg = info[5]
banner0 = info[6]
sdate = str(info[7])[:10]
edate = str(info[8])[:10]
addr1 = info[9]
addr2 = info[10]
pincode = info[11]
full_address = info[15]
state = info[12]
city = info[13]
stime = str(info[18])
#s_time = datetime.strptime(stime,"%H:%M:%S")
#stime = s_time.strftime("%I:%M:%S %p")
etime = str(info[19])
# e_time = datetime.strptime(etime,"%H:%M:%S")
# etime = e_time.strftime("%I:%M:%S %p")
description = info[20]
src_url = info[26]
json0 = {"event id":eventid, "country":countryname, "event name":eventname, "profile image":profileimg, "banner":banner0, "start date":sdate,
"end date":edate, "address 1":addr1, "address 2":addr2, "pincode":pincode, "full address":full_address, "state":state, "city":city,
"start time":stime, "end time":etime, "description":description, "source url":src_url}
json_0.append(json0)
main_json['event info'] = json_0
#tickets
sql1 = """SELECT * FROM tickets WHERE event_id = '%d'""" %event_id
cursor.execute(sql1)
data1 = cursor.fetchall()
for info1 in data1:
tktid = info1[0]
eventid1 = info1[1]
tktname = info1[2]
original_tkt_price = info1[3]
other_charges = info1[4]
other_charges_type = info1[5]
tkt_qty = info1[6]
min_qty = info1[7]
max_qty = info1[8]
qty_left = info1[9]
ticket_msg = info1[10]
ticket_start_date = str(info1[11])[:10]
ticket_start_time = str(info1[11])[11:]
expiry_date = str(info1[12])[:10]
expiry_time = str(info1[12])[11:]
ticket_label= info1[13]
active1 = info1[14]
..........................................................................
i just wrote a small script to port sqlite table to mysql but im realy not sure if i did right.
Im atleast sure, it works to the mysql-connection part, so atleast it already builds mysql connection.
from __future__ import with_statement
import sqlite3
import os
import pymysql
addonPath = "Path-To-SQLITe-Database"
addonPathOrginal = -"Path-To-Database.ini"
connection = sqlite3.connect(os.path.join(addonPath, "db.sqlite"))
#connection.row_factory = sqlite3.Row
connection.text_factory = str
cursor = connection.cursor()
sqliteexecute = cursor.execute
fetchall = cursor.fetchall
databaseinfo = os.path.join(addonPathOrginal, "database.ini")
d = {}
with open(databaseinfo, "r") as fs:
for l in fs.readlines():
l = l.strip(" ").strip("\n")
obj = l.split("=")
if len(obj) != 2: continue
if obj[1] == "": continue
d[obj[0]] = obj[1]
mysqlcon = pymysql.connect(**d)
mysqlcursor = mysqlcon.cursor()
execute = mysqlcursor.execute
execute("SET ##autocommit=1;")
execute("SET sql_notes = 1;")
execute("SET FOREIGN_KEY_CHECKS = 0;")
tablename = "jumptimes" # Convert Table 'jumptimes'
sqliteexecute("SELECT * FROM sqlite_master WHERE type='table' AND tbl_name='%s'" tablename)
#sqliteexecute("SELECT jumptimes FROM sqlite_master")
for x in fetchall():
print "Table: %s" % tablename
#if tablename == "sqlite_sequence": continue
sqliteexecute("SELECT * FROM %s" % tablename)
stuff = fetchall()
if len(stuff) == 0: continue
string = ("%s," * len(stuff[0]))[:-1]
print "Table %s, %i elements, length of string %i" % (tablename, len(stuff),len(stuff[0]))
for y in range(0, len(stuff), 5):
mysqlcursor.executemany("REPLACE INTO " + tablename + " VALUES (" + string + ")", stuff[y:y+5])
connection.close()
execute("SET FOREIGN_KEY_CHECKS = 1;")
mysqlcon.commit()
mysqlcon.close()
database.ini
host=""
user=""
passwd=""
db=""