I am trying to write a python script to select records created within the past 7 hours (date field - database time) using a where-clause within arcpy. The table is ArcSDE database (Microsoft SQL Server).
I've written a script that calculates the time 7 hours prior to the current time. Then I want to use the "report_time" variable to select the relevant records in a table view but I'm getting an invalid expression error. I've tried to reformat the SQL statement in every way I could think of and still get the invalid expression error (I've kept them in my script and commented them out for reference).
-- Get start and end times for report
start_time= datetime.timedelta(hours = 7)
end_time = datetime.datetime.now()
report_time = end_time-start_time #this is the time that gets used to filter records
-- find all records that are later than or = to report_time
SQL = "created_date >= " + report_time.strftime('%m/%d/%Y')
print SQL
arcpy.SelectLayerByAttribute_management(ViewTable,"NEW_SELECTION", SQL)
-- SQL = "created_date >= " + str(report_time.strftime('%m/%d/%Y'))
-- SQL = '"created_date"<='+ report_time.strftime('%Y/%m/%d')
-- SQL = '"created_date"<='+ report_time.strftime('%m/%d/%Y')
-- SQL = "'created_date'<= "+ report_time.strftime('%m/%d/%Y')
-- SQL = '"created_date"<='+ report_time.strftime('%m/%d/%Y %I:%M:%S %p') - ExecuteError: ERROR 000358: Invalid expression
-- SQL = "'created_date'<= "+ report_time.strftime('%m/%d/%Y %I:%M:%S %p') - ExecuteError: ERROR 000358: Invalid expression
-- SQL = "'created_date'<= "+ str(report_time.strftime('%m/%d/%Y %I:%M:%S %p'))
-- SQL = '"created_date"<='+ str(report_time.strftime('%m/%d/%Y %I:%M:%S %p'))
--SQL = '"created_date"<= report_time.strftime'('%m/%d/%Y %I:%M:%S %p') - TypeError: 'str' object is not callable
--SQL = '"created_date" <= report_time' #this returns an expression error
--SQL = "'created_date' <= report_time" #also tried this - expression error
--SQL = 'created_date'<= report_time # returns error: TypeError: can't compare datetime.datetime to str
2 Answers 2
So I figured it out - @Yanes was close but instead of three sets of double quotes, it needed to be double-single-double. So the following script works:
-- Turn ReportsTable into a View Table
arcpy.MakeTableView_management(ReportsTable, ViewTable)
-- Get start and end times for report
start_time= datetime.timedelta(hours = 24)
end_time = datetime.datetime.now()
report_time = end_time-start_time #this is the time that gets used to filter records
-- find all records that are later than or = to report_time
SQL = "created_date >="+ "'"+report_time.strftime('%Y-%m-%d %H:%M:%S')+"'"
print SQL
-- select records within the specified time range using arcpy
arcpy.SelectLayerByAttribute_management(ViewTable,"NEW_SELECTION", SQL)
-
3
SQL = "created_date >= '{}'".format(report_time.strftime('%Y-%m-%d %H:%M:%S'))
2016年02月05日 23:56:15 +00:00Commented Feb 5, 2016 at 23:56 -
2This is why you should never concatenate strings with +.Tom– Tom2016年02月06日 00:00:11 +00:00Commented Feb 6, 2016 at 0:00
-
great! however check with
arcpy.GetCount_management('ViewTable')
, to see if you've correctly selected records. or addprint arcpy.GetMessages()
after your select by attribute line. To check what it did. Not that I am saying it doesn't work, just wondering because I didn't think specifying field without quotations worked. Also please accept your answer so that people could see the Q has an accepted answer.yanes– yanes2016年02月06日 00:20:00 +00:00Commented Feb 6, 2016 at 0:20 -
1Interesting, because your solution is exactly what I said earlier: "Then it looks like you just need single quotes around the time and not around the field name." Maybe it wasn't clear that I was referring to quotes within the SQL query itself.Tom– Tom2016年02月06日 00:49:01 +00:00Commented Feb 6, 2016 at 0:49
-
1@yanes - good point on using the GetCount tool - I did use that to check the records being selected, I just didn't include that info here - but its useful advice for anyone in the same/similar situationreactFullStackDeveloper– reactFullStackDeveloper2016年02月08日 15:12:33 +00:00Commented Feb 8, 2016 at 15:12
Try wrapping your Where statement with three double quotations so that Arcpy understands it as an expression for your select function not a standalone SQL task - I may be wrong on the reasoning, I will check.
SQL = """ "created_date" >= '{}'""".format(report_time.strftime('%Y-%m-%d %H:%M:%S'))
arcpy.SelectLayerByAttribute_management(ViewTable,"NEW_SELECTION", SQL)
Also why do you have two operands in the SQL?
-
Yanes - thanks for the reply but its still doesn't work - By adding all of the quotes its reading the entire SQL as a string which is incorrect: SQL = """ "created_date >= " report_time.strftime('%m/%d/%Y')""" returns this as the SQL statement: "created_date >= " report_time.strftime('%m/%d/%Y'). Also - someone asked why I had a double operand - that was just a mistake type. Sorry I should have proofed that betterreactFullStackDeveloper– reactFullStackDeveloper2016年02月05日 22:40:41 +00:00Commented Feb 5, 2016 at 22:40
-
1Help me understand the SQL isn't it supposed to be a simple statement where: you are looking at a field named
"Created_date"
and selecting all the records that are later or on the date specified by your variablereport_time.strftime('%m/%d/%Y')
. In that case this statement should work. 2 things. 1. please confirmcreated_date
is your field, 2. confirm that the variablereport_time.strftime('%m/%d/%Y')
doesn't give you error, when run on its own.yanes– yanes2016年02月05日 22:56:59 +00:00Commented Feb 5, 2016 at 22:56 -
Also Vince's comment under the original post is valid, check in a GIS software how exactly the time/date is formatted in your table your
report_time.strftime('%m/%d/%Y')
need to reproduce the exact format. You can also use searchcursor to print your records out in python and see the format.yanes– yanes2016年02月05日 23:03:43 +00:00Commented Feb 5, 2016 at 23:03 -
1Thank you for your input. I figured it out. Please see my post belowreactFullStackDeveloper– reactFullStackDeveloper2016年02月05日 23:55:22 +00:00Commented Feb 5, 2016 at 23:55
-
1@Midavalo, thanks! for the correction, it was a mistake! I have edited it now. I didn't know about the second option, good to know. It looks less of a coloring book without the triple double quotes :). I am not sure if I remember correctly - there is an unimaginative alternative that goes as -
/"created_date >= '{}'/".format(report_time.strftime('%Y-%m-%d %H:%M:%S'))
yanes– yanes2016年02月06日 02:28:12 +00:00Commented Feb 6, 2016 at 2:28
Explore related questions
See similar questions with these tags.
created_date >= somestaticdate
and checking that part works?WHERE
clause as it will be used by the database.