Error while updating column in mysql using python - python

Basically what my code does is simply update the database I have created where all the column are of 'varchar' format. My code is able to create a new entry when the time frame is '10:00-10:15'. However, when it is unable to update it when the time frame becomes '10:15-10:30' or basically any other time frame. My code is below:
import time
import MySQLdb
from MySQLdb import *
import datetime
import json
date = time.localtime()
year_mon_date_day = [date.tm_year, date.tm_mon, date.tm_mday, date.tm_wday]
column = ''
if date.tm_hour==10:
if date.tm_min<=15:
column = "10:00-10:15"
elif date.tm_min<=30:
column = "10:15-10:30"
elif date.tm_min <= 45:
column = "10:30-10:45"
elif date.tm_min <= 60:
column = "10:45-11:00"
elif date.tm_hour==11:
if date.tm_min<=15:
column = "11:00-11:15"
elif date.tm_min<=30:
column = "11:15-11:30"
elif date.tm_min <= 45:
column = "11:30-11:45"
elif date.tm_min <= 60:
column = "11:45-12:00"
elif date.tm_hour==12:
if date.tm_min<=15:
column = "12:00-12:15"
elif date.tm_min<=30:
column = "12:15-12:30"
elif date.tm_min <= 45:
column = "12:30-12:45"
elif date.tm_min <= 60:
column = "12:45-01:00"
elif date.tm_hour==13:
if date.tm_min<=15:
column = "01:00-01:15"
elif date.tm_min<=30:
column = "01:15-01:30"
elif date.tm_min <= 45:
column = "01:30-01:45"
elif date.tm_min <= 60:
column = "01:45-02:00"
else:
pass
db = MySQLdb.connect(host='localhost', user='root', passwd='4747',db='traffic_record')
cursor=db.cursor()
if column == "10:00-10:15":
query = '''INSERT INTO `traffic_record`.`RoadA` ( `Date`,`Day`,`''' + column + '''`) VALUES ('%s','%s','%s')'''
value = (year_mon_date_day,date.tm_wday, 9)
else:
query = '''UPDATE `traffic_record`.`RoadA` SET `''' + column + '''`=`%s` WHERE `Date`=''' + str(year_mon_date_day) + '''`'''
value = (3)
cursor.execute(query, value)
db.commit()
db.close()
My code gives following error when I try to run it in any other time frame other than '10:00-10:15'. I receive the following error:
/usr/bin/python2.7 /home/sparsha/PycharmProjects/MachineLearning/fill_table.py
Traceback (most recent call last):
File "/home/sparsha/PycharmProjects/MachineLearning/fill_table.py", line 83, in <module>
cursor.execute(query, value)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 187, in execute
query = query % tuple([db.literal(item) for item in args])
TypeError: 'int' object is not iterable
Process finished with exit code 1
I am unable to solve it. Any help will be highly appreciated. Thanks.

You should set your value as an iterable:
value = (3,)
# ^
What you have (3) is an integer with a grouping parenthesis. The parenthesis does not make the integer an iterable. But adding that comma makes it a singleton tuple which is what you want.

Related

Relocate the table index in python 3

Query = search _entry.get()
Sql = *SELECT FROM customers where last_name = %s"
Data = (query,)
Result = my_cursor. Execute (sql, data)
Result = my_cursor. fetchall ()
If not result :
Result = "record not found... "
Query_label = Label(search _customer _window, text =result)
Query_label. Place (x=40,y=130)
else :
For index, x in enumerate (result) :
Num =0
Index +=2
For y in x:
Query_label = Label(search _customer_window, text=y)
Query_label.grid(row=index,column=num)
Num +=1
I set the value of index to 2 but nothing happens. Thanks for your help.
When I run the program, the label (query_lqbel) is shown at top left side of the window (row 0, column =0), how can I change the location of label. Its actually a label on which some data are shown.

How create a sqlalchemy delete query with multiples parameter from a loop

I'm new in python and sqlalchemy.
I already have a delete method working if I construct the where conditions by hand.
Now, I need to read the columns and values from an enter request in yaml format and create the where conditions.
#enter data as yaml
items:
- item:
table: [MyTable,OtherTable]
filters:
field_id: 1234
#other_id: null
Here is what I try and can't go ahead:
for i in use_case_cfg['items']:
item = i.get('item')
for t in item['table']:
if item['filters']:
filters = item['filters']
where_conditions = ''
count = 0
for column, value in filters.items():
aux = str(getattr(t, column) == bindparam(value))
if count == 0:
where_conditions += aux
else:
where_conditions += ', ' + aux
count += 1
to_delete = inv[t].__table__.delete().where(text(where_conditions))
#to_delete = t.__table__.delete().where(getattr(t, column) == value)
else:
to_delete = inv[t].__table__.delete()
CoreData.session.execute(to_delete)
To me, it looks ok, but when I run, I got the error below:
sqlalchemy.exc.StatementError: (sqlalchemy.exc.InvalidRequestError) A value is required for bind parameter '9876'
[SQL: DELETE FROM MyTable WHERE "MyTable".field_id = %(1234)s]
[parameters: [{}]]
(Background on this error at: http://sqlalche.me/e/cd3x)
Can someone explain to me what is wrong or the proper way to do it?
Thanks.
There are two problems with the code.
Firstly,
str(getattr(t, column) == bindparam(value))
is binding the value as a placeholder, so you end up with
WHERE f2 = :Bob
but it should be the name that maps to the value in filters (so the column name in your case), so you end up with
WHERE f2 = :f2
Secondly, multiple WHERE conditions are being joined with a comma, but you should use AND or OR, depending on what you are trying to do.
Given a model Foo:
class Foo(Base):
__tablename__ = 'foo'
id = sa.Column(sa.Integer, primary_key=True)
f1 = sa.Column(sa.Integer)
f2 = sa.Column(sa.String)
Here's a working version of a segment of your code:
filters = {'f1': 2, 'f2': 'Bob'}
t = Foo
where_conditions = ''
count = 0
for column in filters:
aux = str(getattr(t, column) == sa.bindparam(column))
if count == 0:
where_conditions += aux
else:
where_conditions += ' AND ' + aux
count += 1
to_delete = t.__table__.delete().where(sa.text(where_conditions))
print(to_delete)
session.execute(to_delete, filters)
If you aren't obliged to construct the WHERE conditions as strings, you can do it like this:
where_conditions = [(getattr(t, column) == sa.bindparam(column))
for column in filters]
to_delete = t.__table__.delete().where(sa.and_(*where_conditions))
session.execute(to_delete, filters)

How do I update a value in a dataframe in a loop?

I am trying to update a rating row by row. I have one dataframe of players, that all start with the same rating. For each match, I want the rating to change. Another dataframe contains results of each match.
import pandas as pd
gamesdata = [['paul','tom'],['paul','lisa'],['tom','paul'],['lisa','tom'],['paul','lisa'],['lisa','tom'],['paul','tom']]
games = pd.DataFrame(gamesdata, columns = ['Winner', 'Looser'])
playersdata= ['lisa','paul','tom']
players = pd.DataFrame(playersdata, columns = ['Name'])
mean_elo = 1000
elo_width = 400
k_factor = 64
players['elo'] = mean_elo
def update_elo(winner_elo, loser_elo):
expected_win = expected_result(winner_elo, loser_elo)
change_in_elo = k_factor * (1-expected_win)
winner_elo += change_in_elo
loser_elo -= change_in_elo
return winner_elo, loser_elo
def expected_result(elo_a, elo_b):
expect_a = 1.0/(1+10**((elo_b - elo_a)/elo_width))
return expect_a
for index, row in games.iterrows():
winnername = row['Winner']
losername = row['Looser']
web = players['elo'].loc[players['Name'] == winnername].values[0]
wIndex = players.loc[players['Name'] == winnername]
#I want to return just the index, so I can update the value
print(wIndex)
leb = players['elo'].loc[players['Name'] == losername].values[0]
print('Winner Elo before: ' + str(web))
winner_elo, looser_elo = update_elo(web, leb)
print('Winner Elo after: ' + str(winner_elo))
#here I want to update value
#players.at[wIndex,'elo']=winner_elo
I am trying to update the value in the players table using
players.at[wIndex,'elo']=winner_elo
but i struggle to get the index with this code:
wIndex = players.loc[players['Name'] == winnername]
Found a sollution:
wIndex = players.loc[players['Name'] == winnername].index.values
Can't believe i missed that

How to check limit range from csv file in python script

I am trying to fetch some values from database and need to check some lower and upper limits of a variables which are store in a text file like this and they are separated by \t. the text file looks like
Variable lower_limit upper_limit
temperature 20 40
pressure 0 100
temperature2 0 30
temperature3 20 25
and the data in database looks like
usec temperature_data temperature2_data
1456411800 25 15
1456412400 45 25
1456413000 28 19
So i start with checking first whether the variable is in the text file, if yes then i would need to check the limits of that variable. until now i am only successful in verifying the name of the variable, but i am unable to check the limits.
my code is as follow
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime as dt
import sys
import time
import datetime
import calendar
import numpy as np
import mysql.connector
import datetime
import numpy as np
import pandas as pd
import mysql.connector
from mysql.connector import errorcode
# starting day, month and year
start_day = dt.datetime(2016, 02, 25)
# total number of dates to visualize
number = 11
num_total = 11
# enter limit range
upper_limit = 250 # these are hardcode values which i want to
replace and instead of hard code , i want to
check these limits values from the text file
lower_limit = 0
# start day in epoch time format
start_time = 1456411800
# variable name and filepath
filepath = '/home/robbyy/files/limit.txt'
vari_name = 'temperature2'
# database name, user and password details and query to fetch respective data
usr = 'roby'
password = 'xxxx'
db_name = 'roby_data'
insert_query = ("SELECT usec , temperature2_data "
"FROM rob_table WHERE usec >= %s "
"AND usec <= %s")
def generate_data():
num = num_total
cnx = mysql.connector.connect(user=usr, password=password,
database=db_name)
cursor = cnx.cursor()
query = insert_query
for i in range(number):
current_start_ts = (start_time + (i*86400))
current_day = datetime.datetime.fromtimestamp(current_start_ts)
# print 'cd: ', current_day
current_end_ts = (start_time + (i*86400)) + 86399
cursor.execute(query, (current_start_ts * 1000000,
current_end_ts * 1000000))
rows = cursor.fetchall()
rows_arr = np.array(rows)
# print 'rows all here li: ', rows
with open(filepath, 'r') as f:
limit_file = f.read()
limits = {}
for line in limit_file.splitlines():
print 'line to see:', line
variable, lower, upper = line.split()
if not variable == 'Variable':
limits[variable] = {'lower': int(lower),
'upper': int(upper)}
print 'limits: ', limits
if vari_name in data:
pass
if len(rows_arr) == 0:
continue
# print 'no data is here'
else:
for item, index in rows_arr:
if index >= upper_limit or index <= lower_limit:
print 'data exceeds limit: ', index
else:
continue
# print 'data is within range: ', index
else:
print 'sorry: this variable name is invalid'
start = start_day
dates = [start + dt.timedelta(days=i) for i in range(num)]
return dates
def main():
dates = generate_data()
main()
If someone helps me or guide me how to check the lower and upper limits from the text file for the required variable instead of giving hard coded values in the script. i would be grateful
thanks
just parse the limits file and for example create a dict out of it. Something like this.
def parse_limits(file):
with open(file, 'r') as f:
limit_file = f.read()
limits = {}
for line in limit_file.splitlines():
variable, lower, upper = line.split()
if not variable == 'Variable':
limits[variable] = {'lower': int(lower),
'upper': int(upper)}
return limits
That would result in a nested dict as follows:
{
'pressure': {'upper': 100, 'lower': 0},
'temperature2': {'upper': 30, 'lower': 0},
'temperature': {'upper': 40, 'lower': 20},
'temperature3': {'upper': 25, 'lower': 20}
}
Edit:
As requested your final code might look s.th. like this:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime as dt
import sys
import time
import datetime
import calendar
import numpy as np
import mysql.connector
import datetime
import numpy as np
import pandas as pd
import mysql.connector
from mysql.connector import errorcode
# starting day, month and year
start_day = dt.datetime(2016, 02, 25)
# total number of dates to visualize
number = 11
num_total = 11
# enter limit range
upper_limit = 250 # these are hardcode values which i want to
replace and instead of hard code , i want to
check these limits values from the text file
lower_limit = 0
# start day in epoch time format
start_time = 1456411800
# variable name and filepath
filepath = '/home/robbyy/files/limit.txt'
vari_name = 'temperature2'
# database name, user and password details and query to fetch respective data
usr = 'roby'
password = 'xxxx'
db_name = 'roby_data'
insert_query = ("SELECT usec , temperature2_data "
"FROM rob_table WHERE usec >= %s "
"AND usec <= %s")
def parse_limits(file):
with open(file, 'r') as f:
limit_file = f.read()
limits = {}
for line in limit_file.splitlines():
variable, lower, upper = line.split()
if not variable == 'Variable':
limits[variable] = {'lower': int(lower),
'upper': int(upper)}
return limits
limits = parse_limits(filepath)
def generate_data():
num = num_total
cnx = mysql.connector.connect(user=usr, password=password,
database=db_name)
cursor = cnx.cursor()
query = insert_query
for i in range(number):
current_start_ts = (start_time + (i*86400))
current_day = datetime.datetime.fromtimestamp(current_start_ts)
# print 'cd: ', current_day
current_end_ts = (start_time + (i*86400)) + 86399
cursor.execute(query, (current_start_ts * 1000000,
current_end_ts * 1000000))
rows = cursor.fetchall()
rows_arr = np.array(rows)
# print 'rows all here li: ', rows
print 'limits: ', limits
if vari_name in data:
if len(rows_arr) == 0:
continue
# print 'no data is here'
else:
for item, index in rows_arr:
if index >= limits[vari_name]['upper'] or
index <= limits[vari_name]['lower']:
print 'data exceeds limit: ', index
else:
continue
# print 'data is within range: ', index
else:
print 'sorry: this variable name is invalid'
start = start_day
dates = [start + dt.timedelta(days=i) for i in range(num)]
return dates
def main():
dates = generate_data()
main()

Tuple indices must be integers when building a dictionary

I am taking an Udacity programming course and have been sitting on the same problem for a week. I finally think I am close to getting it right, but I don't get the last objection. Here is my code:
def process_file(f):
# This is example of the datastructure you should return
# Each item in the list should be a dictionary containing all the relevant data
# Note - year, month, and the flight data should be integers
# You should skip the rows that contain the TOTAL data for a year
# data = [{"courier": "FL",
# "airport": "ATL",
# "year": 2012,
# "month": 12,
# "flights": {"domestic": 100,
# "international": 100}
# },
# {"courier": "..."}
# ]
data = []
info = {}
info["courier"], info["airport"] = f[:6].split("-")
with open("{}/{}".format(datadir, f), "r") as html:
soup = BeautifulSoup(html)
car = str(html)[17:19]
airp = str(html)[20:23]
mydict = {}
x = 0
table = soup.find("table", {"class": "dataTDRight"})
rows = table.find_all('tr')
for row in rows:
cells = row.find_all('td')
year = cells[0].get_text()
year = (year.encode('ascii'))
Month = cells[1].get_text()
Month = (Month.encode('ascii'))
domestic = cells[2].get_text()
domestic = (domestic.encode('ascii'))
international = cells[3].get_text()
international = (international.encode('ascii'))
if Month != "Month" and Month != "TOTAL":
Month = int(Month)
year = int(year)
domestic = int(domestic.replace(',', ''))
international = int(international.replace(',', ''))
mydict['courier'] = car
mydict['airport'] = airp
mydict['year'] = year
mydict['month'] = Month
mydict['flights'] = (domestic, international)
data.append(mydict.copy())
#print type(domestic)
#print mydict
print data
return data
def test():
print "Running a simple test..."
open_zip(datadir)
files = process_all(datadir)
data = []
for f in files:
data += process_file(f)
assert len(data) == 399
for entry in data[:3]:
assert type(entry["year"]) == int
assert type(entry["month"]) == int
assert type(entry["flights"]["domestic"]) == int
assert len(entry["airport"]) == 3
assert len(entry["courier"]) == 2
assert data[-1]["airport"] == "ATL"
assert data[-1]["flights"] == {'international': 108289, 'domestic': 701425}
print "... success!"
The error message I get is:
Traceback (most recent call last):
File "vm_main.py", line 33, in <module>
import main
File "/tmp/vmuser_elbzlfkcpw/main.py", line 2, in <module>
import studentMain
File "/tmp/vmuser_elbzlfkcpw/studentMain.py", line 2, in <module>
process.test()
File "/tmp/vmuser_elbzlfkcpw/process.py", line 114, in test
assert type(entry["flights"]["domestic"]) == int
TypeError: tuple indices must be integers, not str
I am a total beginner, I checked both the type of domestic, and international, they are both int.
Can anybody tell me where I can look up or what I did wrong?
You created a tuple here:
mydict['flights'] = (domestic, international)
so mydict['flights'] is a tuple. But you try to treat it as a dictionary here:
assert type(entry["flights"]["domestic"]) == int
That won't work; you'll need to use integer indices here:
assert type(entry["flights"][0]) == int
or better still, use isinstance() to test for types:
assert isinstance(entry["flights"][0], int)
Here you assign your data mydict['flights'] as a tuple.
def process_file(f):
# Omitted code...
mydict['flights'] = (domestic, international)
Your error then comes from an illegal access to that data type. You are attempting to access the first item of that tuple by the name of variable you used in assignment:
assert type(entry["flights"]["domestic"]) == int
You either need to access your data via an integer index:
assert type(entry["flights"][0]) == int
Or you need to change your assignment to:
mydict['flights'] = {"domestic":domestic, "international":international}
tuples are immutable data types which are indexed by integers. The type of access you are attempting is typical of a dictionary, where indexes can be of any type.

Categories