SQLAlchemy: Formatting a db.DateTime() column result - datetime

I have a relative simple SQLAlchemy query (on an MySQL database):
my_date = db.session.query(func.max(MyTable.date_column)).one()
The queried column is of type db.DateTime().
Now I want to format the returned date in my_date:
my_date.isoformat() # fails
my_date.strftime("%Y-%m-%d %H:%M:%S %z") # fails
What is this object I get as result and what do I have to do to get a datetime object that can be formatted?
When I use the debugger to inspect the returned object I see the following: (datetime.datetime(2016, 1, 28, 12, 35, 17),) - but a real Python datetime.datetime object looks different in the debugger.
dir(my_date) returns the following:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__module__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__',
'__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__',
'_asdict', '_fields', '_real_fields', 'count', 'index', 'keys']

one() returns result as KeyedTuple.
You can use scalar()
my_date = db.session.query(func.max(MyTable.date_column)).scalar()
or get value from tuple
my_date = db.session.query(func.max(MyTable.date_column)).one()[0]

Related

extracting data from nested dictionary by python

I am trying to extract data from a JSON file, and am still not clear about the error coming. My data is like this:
"Tracker":{"Sep 30, 2021":{"DC":4,"DN":"0:0",
DC = {}
for day, daily_data in read_content['Tracker'].items():
for value in daily_data['Disturbances Count']:
DC[datetime] = value
Im getting the following error
---------------------------------------------------------------------------
TypeError: 'int' object is not iterable
The solution for the above code only to add str
DC = {}
for day, daily_data in read_content['Tracker'].items():
for value in str(daily_data['Disturbances Count']):
DC[datetime] = value

python convert a list of dates as strings to a list of dates

I have a list of dates that gets imported as strings. I've tried a bunch of different things to convert it to a list of dates. Doesn't matter how I do it I get an error.
#import valid dates from map file as list
valdts = dfmap.loc[row, 'valdata'].split(', ')
print(valdts)
>>
['1/1/1990', '6/6/1990', '7/4/1776']
#convert strings to dates
attempt1:
valdts = [d.strftime('%Y-%m-%d') for d in valdts]
>>
AttributeError: 'str' object has no attribute 'strftime'
attempt2:
a = [date_obj.strftime('%Y%m%d') for date_obj in valdts]
>>
AttributeError: 'str' object has no attribute 'strftime'
attempt3:
a = datetime.strptime(valdts, '%d %b %Y')
>>
TypeError: strptime() argument 1 must be str, not list
attempt4:
a = valdts.sort(key = lambda dt: datetime.strptime(dt, '%d %m %Y'))
>>
ValueError: time data '1/1/1990' does not match format '%d %m %Y'
attempt5:
for dt in valdts:
dt = dt.replace('/',',')
print(dt)
c = datetime.strptime('.'.join(str(i) for i in dt).zfill(8), "%Y.%m.%d")
>>
'1,1,1990'
ValueError: time data '1.,.1.,.1.9.9.0' does not match format '%Y.%m.%d'
attempt6:
for dt in valdts:
dt = dt.replace('/',',')
datetime.strptime(dt, '%d %m %Y')
>>
ValueError: time data '1,1,1990' does not match format '%d %m %Y'
I'm getting quite frustrated. The different approaches above are based on responses to similar but not quite the same questions posted by others. The question most similar to mine has been downvoted. Am I trying to do something stupid? Would really appreciate some help here. Thanks.
Note: datetime.datetime gives me an error. AttributeError: type object 'datetime.datetime' has no attribute 'datetime' but just datetime works for other parts of my code.
This is the work around I finally came up with. But would welcome a better method that doesn't require splitting each date.
valdts = dfmap.loc[row, 'valdata'].split(', ')
print(valdts)
>>
['1/1/1990', '6/6/1990', '7/4/1776']
for dt in valdts:
ldt = dt.split('/')
valdt = datetime(int(ldt[2]), int(ldt[1]), int(ldt[0]))
ldates.append(valdt)
print(ldt)
>>
note1: datetime.datetime didn't work for me because of the way I'd imported datetime. See excellent explanations here.
note2: converting the individual numbers to int was crucial. nothing else worked for me. Credit to the solution provided by #waitingkuo in the same link above.

R sprintf in sqldf's like

I would like to do a looping query in R using sqldf to that select all non-NULL X.1 variable with date "11/12/2015" and at 9AM. Example :
StartDate X.1
11/12/2015 09:14 A
11/12/2015 09:36
11/12/2015 09:54 A
The date is in variable that generated from other query
nullob<-0
dayminnull<-as.numeric(sqldf("SELECT substr(Min(StartDate),1,03)as hari from testes")) # this produce "11/12/2015"
for (i in 1 : 12){
dday<-mdy(dayminnull)+days(i) #go to next day
sqlsql <- sprintf("SELECT count([X.1]) FROM testes where StartDate like '% \%s 09: %'", dday)
x[i]<-sqldf(sqlsql)
nullob<-nullob+x[i]
}
And it comes with error : Error in sprintf("SELECT count([X.1]) FROM testes WHERE StartDate like '%%s 09%'", :
unrecognised format specification '%'
Please hellp. thank you in advance
It's not super clear in the documentation, but a % followed by a %, that is %%, is the way to tell sprintf to use a literal %. We can test this fairly easily:
sprintf("%% %s %%", "hi")
[1] "% hi %"
For your query string, this should work:
sprintf("SELECT count([X.1]) FROM testes where StartDate like '%% %s 09: %%'", dday)
From ?sprintf:
The string fmt contains normal characters, which are passed through to
the output string, and also conversion specifications which operate on
the arguments provided through .... The allowed conversion
specifications start with a % and end with one of the letters in the
set aAdifeEgGosxX%. These letters denote the following types:
... [Documentation on aAdifeEgGosxX]
%: Literal % (none of the extra formatting characters given below are permitted in this case).

IndexError: list index out of range, scores.append( (fields[0], fields[1]))

I'm trying to read a file and put contents in a list. I have done this mnay times before and it has worked but this time it throws back the error "list index out of range".
the code is:
with open("File.txt") as f:
scores = []
for line in f:
fields = line.split()
scores.append( (fields[0], fields[1]))
print(scores)
The text file is in the format;
Alpha:[0, 1]
Bravo:[0, 0]
Charlie:[60, 8, 901]
Foxtrot:[0]
I cant see why it is giving me this problem. Is it because I have more than one value for each item? Or is it the fact that I have a colon in my text file?
How can I get around this problem?
Thanks
If I understand you well this code will print you desired result:
import re
with open("File.txt") as f:
# Let's make dictionary for scores {name:scores}.
scores = {}
# Define regular expressin to parse team name and team scores from line.
patternScore = '\[([^\]]+)\]'
patternName = '(.*):'
for line in f:
# Find value for team name and its scores.
fields = re.search(patternScore, line).groups()[0].split(', ')
name = re.search(patternName, line).groups()[0]
# Update dictionary with new value.
scores[name] = fields
# Print output first goes first element of keyValue in dict then goes keyName
for key in scores:
print (scores[key][0] + ':' + key)
You will recieve following output:
60:Charlie
0:Alpha
0:Bravo
0:Foxtrot

Groovy: How do you initialise and compare date/time values from different timezones?

I need to standardise and compare date/time fields that are in differnt timezones. eg How do you find the time difference between the following two times?...
"18-05-2012 09:29:41 +0800"
"18-05-2012 09:29:21 +0900"
What's the best way to initialise standard varaibles with the date/time?
The output needs to display the difference and normalised data in a timezone (eg +0100) that is different to the incoming values and different to the local environment.
Expected Output:
18-05-2012 02:29:41 +0100
18-05-2012 01:29:21 +0100
Difference: 01:00:20
import java.text.SimpleDateFormat
def dates = ["18-05-2012 09:29:41 +0800",
"18-05-2012 09:29:21 +0900"].collect{
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z").parse(it)
}
def dayDiffFormatter = new SimpleDateFormat("HH:mm:ss")
dayDiffFormatter.setTimeZone(TimeZone.getTimeZone("UTC"))
println dates[0]
println dates[1]
println "Difference "+dayDiffFormatter.format(new Date(dates[0].time-dates[1].time))
wow. doesn't look readable, does it?
Or, use the JodaTime package
#Grab( 'joda-time:joda-time:2.1' )
import org.joda.time.*
import org.joda.time.format.*
String a = "18-05-2012 09:29:41 +0800"
String b = "18-05-2012 09:29:21 +0900"
DateTimeFormatter dtf = DateTimeFormat.forPattern( "dd-MM-yyyy HH:mm:ss Z" );
def start = dtf.parseDateTime( a )
def end = dtf.parseDateTime( b )
assert 1 == Hours.hoursBetween( end, start ).hours
Solution:
Groovy/Java Date objects are stored as the number of milliseconds after
1970 and so do not contain any timezone information directly
Use Date.parse method to initialise the new date to the specified format
Use SimpleDateFormat class to specify the required output format
Use SimpleDateFormat.setTimeZone to specifiy the timezone of the output
data
By using European/London timezone rather than GMT it will
automatically adjusts for day light savings time
See here for a full list of the options for date time patterns
-
import java.text.SimpleDateFormat
import java.text.DateFormat
//Initialise the dates by parsing to the specified format
Date timeDate1 = new Date().parse("dd-MM-yyyy HH:mm:ss Z","18-05-2012 09:29:41 +0800")
Date timeDate2 = new Date().parse("dd-MM-yyyy HH:mm:ss Z","18-05-2012 09:29:21 +0900")
DateFormat yearTimeformatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z")
DateFormat dayDifferenceFormatter= new SimpleDateFormat("HH:mm:ss") //All times differences will be less than a day
// The output should contain the format in UK time (including day light savings if necessary)
yearTimeformatter.setTimeZone(TimeZone.getTimeZone("Europe/London"))
// Set to UTC. This is to store only the difference so we don't want the formatter making further adjustments
dayDifferenceFormatter.setTimeZone(TimeZone.getTimeZone("UTC"))
// Calculate difference by first converting to the number of milliseconds
msDiff = timeDate1.getTime() - timeDate2.getTime()
Date differenceDate = new Date(msDiff)
println yearTimeformatter.format(timeDate1)
println yearTimeformatter.format(timeDate2)
println "Difference " + dayDifferenceFormatter.format(differenceDate)

Resources