I'm making Car parking system, and I have some difficulities with SQL database.
I'm selecting data from SQL database, but I need to get the time correctly that I could use it for further calculations. So for example I need to get the time that was inserted to database as VARCHAR, maybe the bad thing is that I needed to use other method as TIME, but that's not the case. The thing I need is to use this line Started_Parking = row [3]. This should get the time from database and after that, I should be able to see the time difference from the start when car was registered and current time. By doing that I should be able to calculate the sum which the "User" should pay for parking.
So by short I just need to somehow get the time from database and use it for calculations. Here's my code, I also get errors when compiling :
Error while fetching data from PostgreSQL unsupported operand type(s)
for -: 'datetime.datetime' and 'str'
try:
connection = psycopg2.connect(user="postgres",
password="Dziugas420",
host="127.0.0.1",
port="5432",
database="postgres")
cursor = connection.cursor()
postgreSQL_select_Query = "select * from vartotojai WHERE carnum=('%s')" % car_numb
cursor.execute(postgreSQL_select_Query) # PALEIST KOMANDA
vartotoju_data = cursor.fetchall() # READ DATA
print(" CAR DETAILS: ")
for row in vartotoju_data:
print("Current ID: ", row[0])
print("Car Number: ", row[1])
print("Parked on: ", row[3], "\n")
Pay_Time = datetime.datetime.now()
Started_Parking = row [3]
Prastovetas_Laikas = Pay_Time - Started_Parking
print(Prastovetas_Laikas)
# NOW LET'S CHECK IF THE TIME DIFFERENCE IS WORKING, LET'S SEE THE DIFFERENCE AFTER 20SECS.
time.sleep(20)
Pay_Time2 = datetime.datetime.now()
Prastovetas_Laikas2 = Pay_Time2 - Started_Parking
print(Prastovetas_Laikas2)`
**EDIT
Here's the code I use to import this time into database:
Car_Reg_Time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
postgres_insert_query = """ INSERT INTO vartotojai (CARNUM, TIME, LAIKAS) VALUES (%s,%s, %s)"""
record_to_insert = (car_numb, Reg_Tikslus_Laikas, Car_Reg_Time)
And here's the table of my database:
! laikas in database is when car was registered, the time in database is the time when the injection was made.
Prastovetas_Laikas = Pay_Time - Started_Parking
will not work
since Pay_Time is datetime.datetime and Started_Parking is str
you need to try to use datetime.strptime() to convert Started_Parking to correct type
and you want to store them as str in your DB using str(mydate)
Related
i am trying to insert a record of time-type variable called duration that is gotten by using the datetime package..
duration_start_time = datetime.now()
time.sleep(5)
duration_end_time = datetime.now()
duration = duration_end_time - duration_start_time
print(f"{fileName} took", duration, "to download")
insert_duration = "INSERT INTO ImportHistory(Duration) VALUES (%s)"
mycursor.execute(insert_duration, duration)
connection.commit()
the error i am getting is 'ValueError: Could not process parameters'
does anyone have any idea what i am doing wrong? let me know if i can clarify any necessary information i might've missed!
The argument must be a tuple, even if there's just one parameter:
mycursor.execute(insert_duration, (duration,))
I am running into an issue building a random project for myself. I am trying to record entries into a mysql database that the user types in. I am storing them in a dictionary. The error message is
while self.nextset():
AttributeError: 'str' object has no attribute 'nextset'
I have googled and searched for this issue, but I only find issues kind of like it but not the same error.
My table headers in mysql db match the dictionary keys. I do realize I have issues with selection (2) but my error and what I am troubleshooting now is just when I select option (1).
import mysql
import pymysql
from datetime import date, datetime, timedelta
cursor = pymysql.cursors.Cursor
# Function for adding a new entry
def new_entry(name, date, task, time, notes):
# Build dictionary with new entry information
myDict = {
'Employee': name, # Name of employee
'Date': date, # Date of worked task
'Task': task, # Title of Task
'Time': time, # Time spent on task
'Notes': notes # Notes on the task
}
table = ('timesheet')
placeholders = ', '.join(['%s'] * len(myDict))
columns = ', '.join(myDict.keys())
sql = "INSERT INTO %s ( %s ) VALUES ( %s )" % (table, columns,
placeholders)
pymysql.cursors.Cursor.execute(sql, myDict)
#list all entries for a particular employee
def previous_entries(emp_name):
pymysql.cursors.Cursor.execute(
"SELECT * from user_data WHERE Name = %s", (emp_name,))
#list all entries that match a date or search term
#def search_entries():
# return null
#Print a report of this information to the screen, including the date, title
#of task, time spent, employee, and general notes.
if __name__ == '__main__':
#cnx = mysql.connect(user='root', database='me10_mig')
cnx = pymysql.connect(user='root', password='password',
database='me10_mig')
print("Please enter (1), (2), or (3)")
begin = input("Would you like to (1) enter a new entry or (2) display
all
previous entries or (3) display entries that match a date or search
term? ")
if begin == '1':
name = input("Your Name: ")
date = input("Date of Time Worked: ")
task = input("Title of Task: ")
time = input("Time Spent on Task: ")
notes = input("Notes on Time Worked: ")
new_entry(name, date, task, time, notes)
if begin == '2':
name = input("What is the employee name: ")
previous_entries(name)
#if begin == '3':
The error I get says:
Traceback (most recent call last):
File "C:/Users/a089673/Desktop/Python/TeamTreeHouse/Part 4/timesheet.py", line 61, in <module>
new_entry(name, date, task, time, notes)
File "C:/Users/a089673/Desktop/Python/TeamTreeHouse/Part 4/timesheet.py", line 27, in new_entry
pymysql.cursors.Cursor.execute(sql, myDict)
File "C:\Users\a089673\AppData\Roaming\Python\Python36\site packages\pymysql\cursors.py", line 165, in execute
while self.nextset():
AttributeError: 'str' object has no attribute 'nextset'
Process finished with exit code 1
Any suggestions?
I suspect your might stem from using a dict to hold the arguments to .execute(), but not using named string patterns in the SQL statement.
The docs suggest using %s when passing a list or tuple, but rather use %(name)s when passing a dict.
I suggest you try this code:
def new_entry(name, date, task, time, notes):
# Build dictionary with new entry information
myDict = {
'Employee': name, # Name of employee
'Date': date, # Date of worked task
'Task': task, # Title of Task
'Time': time, # Time spent on task
'Notes': notes # Notes on the task
}
table = ('timesheet')
column_list = []
placeholder_list = []
for k in myDict:
column_list.append(k)
placeholder_list.append('%(' + k + ')s')
sql = "INSERT INTO %s ( %s ) VALUES ( %s )" % (
table,
', '.join(column_list),
', '.join(placeholder_list))
pymysql.cursors.Cursor.execute(sql, myDict)
This will also ensure that the column names and the placeholders are in the same order. Your original code did not consider that (remember, iterating over dicts multimple time is not garanteed to give the same order each time).
I totally overlooked the part where you establish a connection to the database. You need to pass that connection as a parameter to new_entry() and use it.
Try this:
def new_entry(cnx, name, date, task, time, notes):
sql = "INSERT INTO timesheet (Employee, Date, Task, Time, Notes) VALUES (%s, %s, %s, %s, %s)"
values = (name, date, task, time, notes)
with cnx.cursor() as cursor:
cursor.execute(sql, values)
cnx = pymysql.connect(user='root', password='password', database='me10_mig')
new_entry(cnx, ...)
I want to retrieve time in the format of "HH:MM" from datetime.timedelta object. I have a table stored in MySQL database. It has time column, which has stored the time in the format,
00:00:00
I have connected to MySQL server using PyMySQL module,
conn = pymysql.connect("localhost", "root", "cloudera", "streaming")
cursor = conn.cursor()
sql = "select * from table1 limit 5;"
cursor.execute(sql)
row = cursor.fetchone()
row[1]
Output is,
datetime.timedelta(0)
I have been through this post Python: How do I get time from a datetime.timedelta object?. But the difference from that question and mine is in output result. For that post, output is
datetime.timedelta(0, 64800)
And for me it is just,
datetime.timedelta(0)
I just don't get it why the output for me is that way. Can anyone please help me in retrieving time. Thanks in advance.
When you type row[1] python prints the repr of the variable - in this case repr of a timedelta is "datetime.timedetla(days, seconds)".
You can stringify it using str but that would give you HH:MM:SS
str(row[1])
-> "23:00:00"
To get HH:MM you can do the following:
(datetime.min + row[1]).strftime("%H:%M")
-> "23:00"
So your code should look like this:
conn = pymysql.connect("localhost", "root", "cloudera", "streaming")
cursor = conn.cursor()
sql = "select * from table1 limit 5;"
cursor.execute(sql)
row = cursor.fetchone()
timestr = (datetime.min + row[1]).strftime("%H:%M")
print(timestr)
I am using postgreSQL with python and the SQL database is such that rows are added regularly. At present, the python program does not know if new data has been added (I used psycopg2 to read rows. But it reads till the end of rows and stops). How can I let my python program constantly search if new data has been added? Or can I let postgreSQL trigger python when a new row is added?
This is what I have currently:
def get_data():
try:
connect = psycopg2.connect(database="yardqueue", user="postgres", password="abcd", host="localhost", port="5432")
except:
print "Could not open database"
cur = connect.cursor()
cur.execute("SELECT id,position FROM container")
rows = cur.fetchall()
for row in rows:
print "ID = ", row[0]
print "Position = ", row[1]
As you see, when I run this, it stops once variable 'row' reaches the last row.
EDIT: Is there a way I can keep my python code running for a specified amount of time? If so, I can make it go through the database until I kill it.
if you want to check out new records we can write (assuming there are no deletions in container table):
from time import sleep
import psycopg2
IDLE_INTERVAL_IN_SECONDS = 2
def get_data():
try:
connect = psycopg2.connect(database="yardqueue", user="postgres",
password="abcd", host="localhost",
port="5432")
except:
print "Could not open database"
# TODO: maybe we should raise new exception?
# or leave default exception?
return
cur = connect.cursor()
previous_rows_count = 0
while True:
cur.execute("SELECT id, position FROM container")
rows_count = cur.rowcount
if rows_count > previous_rows_count:
rows = cur.fetchall()
for row in rows:
print "ID = ", row[0]
print "Position = ", row[1]
previous_rows_count = rows_count
sleep(IDLE_INTERVAL_IN_SECONDS)
if we want to process only new records we can add ordering by id and offset like
from time import sleep
import psycopg2
IDLE_INTERVAL_IN_SECONDS = 2
def get_data():
try:
connect = psycopg2.connect(database="yardqueue", user="postgres",
password="abcd", host="localhost",
port="5432")
except:
# TODO: maybe we should raise new exception?
# or leave default exception?
print "Could not open database"
return
cur = connect.cursor()
rows_count = 0
while True:
cur.execute("SELECT id, position FROM container "
# sorting records by id to get new records data
# assuming that "id" column values are increasing for new records
"ORDER BY id "
# skipping records that we have already processed
"OFFSET {offset}"
.format(offset=rows_count))
rows_count = cur.rowcount
if rows_count > 0:
rows = cur.fetchall()
for row in rows:
print "ID = ", row[0]
print "Position = ", row[1]
sleep(IDLE_INTERVAL_IN_SECONDS)
Unfortunately, a database has no notion of insertion order, so you as the designer must provide an explicit order. If you do not, the order of the rows you fetch (using a new cursor) may change at any time.
Here a possible way is to have a serial field in your table. PostgreSQL implements a serial field through a sequence, which guarantees that each new inserted row gets a serial number greater than all currently existing ones. But:
there can be holes if a transaction requires a serial number and is aborted
if multiple concurrent transactions insert a serial field, the order of the serial field will be the order of the insert commands, not the order of the commit commands. That means that race conditions can result in a wrong order. But it is fine if you have only one writer in the database
An alternative way is to use an insertion date field - the inserting application has to manage it explicitely or you can use a trigger to set it tranparently. PostgreSQL timestamp have a microsecond precision. That means that many rows can have same insertion date value if they are inserted at the same time. Your Python script should read the time before opening a cursor and fetch all rows with an insertion time greater than its last run time. But here again you should care of race conditions...
I'm getting the following error while running my sql in python
/usr/lib/python2.6/site-packages/django/db/backends/mysql/base.py:64: RuntimeWarning: SQLite received a naive datetime (2012-06-22 15:53:43) while time zone support is active.
my query also returns the wrong data.
if i change the time up 2 hours (17:53:43 instead of 15:53:43), my timezone atm is gmt +2 so i think the problem is in the time zone.
how do i change my query to make the sql execute in the way i intend it to?
sql:
sqlQuery = """SELECT w.id, w.serial, w.finishdate, w.weighingtype_id, w.netto, w.bruto, w.deleted
FROM weighing w
LEFT JOIN weighing w1
ON w1.id = w.parent_id
WHERE w.user_id = %(userid)s"""
if date:
sqlQuery = sqlQuery + " AND (w.created = %(date)s OR w.modified > %(date)s)"
edit: added my code for transforming the datetime
data = request.GET.copy()
if 'date' in data:
try:
data['date'] = datetime.datetime.strptime(data['date'], "%Y-%m-%dT%H:%M:%S")
except:
raise error(311)