Storing a TimeDelta in my SQL Server database - python

Table Tasks has 2 datetime columns, StartDate and EndDate. I used python to calculate the difference between these two, resulting in column Time_Difference. See below:
Tasks['Time_Difference'] = Tasks['EndDate'] - Tasks['StartDate']
Avg_Task_Duration = Tasks['Time_Difference'].mean()
Now, I want to store the Avg_Task_Duration value in a Stats table from my SQL Server. It is of type timedelta and looks like this: Timedelta('438 days 09:25:10')
Therefore, I have the following questions:
Is it possible to store a timedelta in my SQL Server? If yes, what data type should the column have?
If not, is there any other alternative?

Unfortunately, SQL Server does not support the ISO SQL standard interval type. You could use time for intervals less than 24 hours but need to store the value in integer units (e.g. seconds) to store longer periods.

Related

What format do we need to use to store data in db.Time?

I'm creating a database with SQLAlchemy and SQLite. I have some database models and one of them needs a time. Not the time-of-the-day sort of time but like when-you-study-for-10-minutes sort of time. What format can we store in db.Time?
Code:
time = db.Column(db.Time, nullable=False)
What you're looking for is a "time interval". SQLite doesn't have that. In fact, it doesn't have a time type at all. So use whatever you want.
I would suggest storing the number of seconds in the interval as an integer. For "15 minutes" you would store 900.
SQLAlchemy does have an Interval type for storing datetime.timedelta objects which you could try. The docs say "the value is stored as a date which is relative to the “epoch” (Jan. 1, 1970)" which I think is just a fancy way to say they'll store the number of seconds.

Find the difference between two dates/times

I generate and insert a time and date into my SQLite3 database in Python with the following command:
connection.execute("INSERT INTO ActiveTable (IDPK, time) VALUES (NULL, datetime('now', 'localtime'))")
The time is stored into the database in an INTEGER field with the format:
2016-07-18 08:58:48
I think that the value is actually stored as a TEXT since Sqlite3 works with type affinity, INTEGER is just left over code that I will probably change.
My goal is to query my database to get this value from a SELECT operation, and then find the difference compared to the current time using python's native time and date modules. My final goal is to have time difference from original insert to now represented similarly to this:
2d:1h:5m
To be inserted into the Database in a new field called TimeDiff.
Is this possible using time, date, or datetime in python? I'm having trouble with the syntax for these modules.
from datetime import datetime
day1 = datetime.strptime("2016-07-18 08:58:48","%Y-%m-%d %H:%M:%S")
day2 = datetime.strptime("2016-02-18 07:58:48","%Y-%m-%d %H:%M:%S")
print(day1 -day2)
Output:
151 days, 1:00:00

Query [large] data records from Proficy Historian?

I'm using the Proficy Historian SDK with python27. I can create a data record object and add the query criteria attributes (sample type, start time, end time, sample interval - in milliseconds) and use datarecord.QueryRecordset() to execute a query.
The problem I'm facing is that method QueryRecordset seems to only work for returning a small number of data sets (a few hundred records at most) i.e. a small date range, otherwise it returns no results for any of the SCADA tags. I can sometimes get it to return more (a few thousand) records by slowly incriminating the date range, but it seems unreliable. So, is there a way to fix this or a different way to do the query or set it up? Most of my queries contain multiple tags. Otherwise, I guess I'll just have to successively execute the query/slide the date range and pull a few hundred records at a time.
Update:
I'm preforming the query using the following steps:
from win32com.client.gencache import EnsureDispatch
from win32com.client import constants as c
import datetime
ihApp = EnsureDispatch('iHistorian_SDK.Server')
drecord = ihApp.Data.NewRecordset()
drecord.Criteria.Tags = ['Tag_1', 'Tag_2', 'Tag_3']
drecord.Criteria.SamplingMode = c.Calculated
drecord.Criteria.CalculationMode = c.Average
drecord.Criteria.Direction = c.Forward
drecord.Criteria.NumberOfSamples = 0 # This is the default value
drecord.Criteria.SamplingInterval = 30*60*1000 # 30 min interval in ms
# I've tried using the win32com pytime type instead of datetime, but it
# doesn't make a difference
drecord.Criteria.StartTime = datetime.datetime(2015, 11, 1)
drecord.Criteria.EndTime = datetime.datetime(2015, 11, 10)
# Run the query
drecord.Fields.Clear()
drecord.Fields.AllFields()
drecord.QueryRecordset()
One problem that may be happening is the use of dates/times in the dd/mm/yyyy hh:mm format. When I create a pytime or datetime object the individual attributes e.g. year, day, month, hour, minute are all correct before and after assignment to drecord.Criteria.StartTime and drecord.Criteria.EndTime, but when I print the variable it always comes out in mm/dd/yyyy hh:mm format, but this is probably due to the object's str or repr method.
So, it turns out there were two properties that could be adjusted to increase the number of samples returned and time before a timeout occurred. Both properties are set on the server object (ihApp):
ihApp.MaximumQueryIntervals = MaximumQueryIntervals # Default is 50000
ihApp.MaximumQueryTime = MaximumQueryTime # Default is 60 (seconds)
Increasing both these values seemed to fix my problems. Some tags definitely seem to take longer to query than others (over the same time period and same sampling method), so increasing the max. query time helped make returning query data more reliable.
When QueryRecordset() completes it returns False if there was an error and doesn't populate any of the data records. The error type can be show using:
drecord.LastError

Time column in mysql table

I want to store a time value in a mysql table,
1345:55
it is 1345 hours and 55 minutes. What type should column have?
And if I want to pass a time variable from python to this column using mysqldb module, which time type should i use in python? datetime.timedelta?
Generally speaking, one can use MySQL's TIME datatype to store time values:
MySQL retrieves and displays TIME values in 'HH:MM:SS' format (or 'HHH:MM:SS' format for large hours values). TIME values may range from '-838:59:59' to '838:59:59'.
Obviously, in your case, this is insufficient for the range of values required. I would therefore suggest that you instead convert the value to an integer number of minutes and store the result in an 4-byte INT UNSIGNED column (capable of storing values in the range 0 to 4294967295, representing 0:00 to 71582788:15).

Handling dates prior to 1970 in a repeatable way in MySQL and Python

In my MySQL database I have dates going back to the mid 1700s which I need to convert somehow to ints in a format similar to Unix time. The value of the int isn't important, so long as I can take a date from either my database or from user input and generate the same int. I need to use MySQL to generate the int on the database side, and python to transform the date from the user.
Normally, the UNIX_TIMESTAMP function, would accomplish this in MySQL, but for dates before 1970, it always returns zero.
The TO_DAYS MySQL function, also could work, but I can't take a date from user input and use Python to create the same values as this function creates in MySQL.
So basically, I need a function like UNIX_TIMESTAMP that works in MySQL and Python for dates between 1700-01-01 and 2100-01-01.
Put another way, this MySQL pseudo-code:
select 1700_UNIX_TIME(date) from table;
Must equal this Python code:
1700_UNIX_TIME(date)
I don't have MySQL here installed, but when I look here: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_to-days - I see an example TO_DAYS('2008-10-07') returning 733687.
The following Python function returns datetime(2008,10,7).toordinal() = 733322, which is 365 less than the MySQL's output.
So take this:
from datetime import datetime
query = '2008-10-07'
nbOfDays = datetime.strptime(query, '%Y-%m-%d').toordinal() + 365
and it should work for dates between 1700 and 2100.
According to the link that you gave,
Given a date date, returns a day number (the number of days since year 0).
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('2007-10-07');
-> 733321
Corresponding numbers in Python:
>>> import datetime
>>> datetime.date(1995,5,1).toordinal()
728414
>>> datetime.date(2007,10,7).toordinal()
732956
So the relationship is : mySQL_int == Python_int + 365 and you can convert in the other direction by using the fromordinal class method:
>>> datetime.date.fromordinal(728779 - 365)
datetime.date(1995, 5, 1)

Categories