Issue with passing parameters to SQL via pyodbc - python

Having trouble passing parameters to a SQL Server query. The query works with raw data, but not when I try to use parameters. SQL is not identifying parameter markers.
The error I get is
The SQL contains 0 parameter markers, but 2 parameters were supplied', 'HY000'
This is my code I'm having issues with:
currenttime = datetime.datetime(year=2021, month=6, day=7, hour=7, minute=0, second=0, microsecond=999999)
print(currenttime)
print(type(currenttime))
starttime = currenttime = datetime.datetime(year=2021, month=6,day=7,hour=6,minute=0,second=0,microsecond=999999)
params = (starttime,currenttime)
sql='''
SET QUOTED_IDENTIFIER OFF
SELECT * FROM OPENQUERY(INSQL, "SELECT DateTime, [AH41_DP04]
FROM WideHistory
WHERE wwRetrievalMode = 'Cyclic'
AND wwResolution = 1000
AND wwVersion = 'Latest'
AND DateTime >= ?
AND DateTime <= ?")
'''
print(type(params))
cursor.execute(sql,params)
for row in cursor:
print(row)``

Related

Getting a syntax error when trying to execute this SQL query in Python

I'm trying to get the script to automatically set the query start time as 6am yesterday (and will set the end time as 6am today once I figure out the Start time error) but I am getting a syntax error (102, b"Incorrect syntax near '06'.DB-Lib error message 20018, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\n").
If I take out the """+StartTime+""" and change to '20211212 07:00:00.000' then it works but I need a way for the script to keep track of the current date rather than going back and changing every day.
from datetime import timedelta
import numpy as np
from pandas import DataFrame
import pandas as pd
import pymssql
from datetime import date, timedelta
today = date.today()
yesterday = today - timedelta(days = 1)
BEGINDATE=yesterday
ENDDATE=today
BEGINDATE=BEGINDATE.strftime("%Y%m%d")
ENDDATE=ENDDATE.strftime("%Y%m%d")
StartTime = BEGINDATE +' 06:00:00:000'
print(StartTime)
Query= """SET NOCOUNT ON
DECLARE #StartDate DateTime
DECLARE #EndDate DateTime
SET #StartDate = """+StartTime+"""
SET #EndDate = '20211213 07:00:00.000'
SET NOCOUNT OFF
SELECT temp.TagName ,DateTime ,Value ,vValue ,MinRaw = ISNULL(Cast(AnalogTag.MinRaw as VarChar(20)),'N/A') ,MaxRaw = ISNULL(Cast(AnalogTag.MaxRaw as VarChar(20)),'N/A') ,Unit = ISNULL(Cast(EngineeringUnit.Unit as VarChar(20)),'N/A') ,StartDateTime From (
SELECT *
FROM History
WHERE History.TagName IN ('S03_FT03_04_TOT01')
AND wwRetrievalMode = 'Cyclic'
AND wwCycleCount = 1440
AND wwVersion = 'Latest'
AND DateTime >= #StartDate
AND DateTime <= #EndDate) temp
LEFT JOIN AnalogTag ON AnalogTag.TagName =temp.TagName
LEFT JOIN EngineeringUnit ON AnalogTag.EUKey = EngineeringUnit.EUKey
WHERE temp.StartDateTime >= #StartDate"""
cur.execute(Query)
print(Query)
Consider running parameterization in Python passed into a prepared SQL statement without declaring # params. Also, keep all variables in datetimes without any string conversion.
Not quite sure what your date ranges require given 6 AM and 7 AM confusion, below calculates range from yesterday at 6 AM to today at 5:59:59 AM (for 24 hours). Adjust as needed. Finally, final WHERE is moved into subquery.
from datetime import datetime, date, timedelta
import numpy as np
from pandas import DataFrame
import pandas as pd
import pymssql
BEGINDATE = datetime.combine(
date.today() - timedelta(days = 1), datetime.min.time()
) + timedelta(hours = 6)
print(BEGINDATE)
# 2021-12-12 06:00:00
ENDDATE = BEGINDATE + timedelta(days = 1) - timedelta(seconds=1)
print(ENDDATE)
# 2021-12-13 05:59:59
### PREPARED STATEMENT WITH %s PLACEHOLDERS
Query= """SELECT temp.TagName
, [DateTime]
, [Value]
, vValue
, MinRaw = ISNULL(CAST(AnalogTag.MinRaw AS VARCHAR(20)), 'N/A')
, MaxRaw = ISNULL(CAST(AnalogTag.MaxRaw AS VARCHAR(20)), 'N/A')
, Unit = ISNULL(CAST(EngineeringUnit.Unit AS VARCHAR(20)), 'N/A')
, StartDateTime
FROM (
SELECT *
FROM History
WHERE History.TagName IN ('S03_FT03_04_TOT01')
AND wwRetrievalMode = 'Cyclic'
AND wwCycleCount = 1440
AND wwVersion = 'Latest'
AND [DateTime] >= %s
AND [DateTime] <= %s
AND StartDateTime >= %s
) temp
LEFT JOIN AnalogTag ON AnalogTag.TagName = temp.TagName
LEFT JOIN EngineeringUnit ON AnalogTag.EUKey = EngineeringUnit.EUKey
"""
# RUN QUERY WITH PARAMETERS
cur.execute(Query, [BEGINDATE, ENDDATE, BEGINDATE])
print(Query)

How to insert today's date in SQL select statement using python?

I'm trying to send today variable into SQL but it is not working.
import datetime from date
today = date.today()
stmt = "select agent_email from customer_interaction_fact where to_date(DT) >= + today + ORDER BY CONVERSATION_CREATED_TIME DESC"
You don't have to compute today's date in Python. Just use the PostgreSQL function CURRENT_DATE:
stmt = "SELECT ... WHERE TO_DATE(DT) >= CURRENT_DATE ..."
What database engine you're using? You'd need to convert the python datetime object into string with format accepted by the database.
# In case YYYY-MM-DD
today_str = str(today)
stmt = f"""select agent_email
from customer_interaction_fact
where to_date(DT) >= datetime({today}, "YYYY-MM-DD")
order by CONVERSATION_CREATED_TIME DESC"""
Another solution, assuming the client (your program) is in the same timezone as the database engine, you could use your database engine datetime.now function. In SQLite for instance datetime('now')
try like below
from datetime import date
today = date.today()
stmt = "select agent_email,aht_in_secs,queueid,EFFORTSCORE from facts.public.customer_interaction_fact where agent_email <> 'Bot' and aht_in_secs is not NULL and to_date(DT) >=" + today + "ORDER BY CONVERSATION_CREATED_TIME DESC"

Python convert timedelta type to sql time type

Invalid data type when using Python time delta result and saving to time type in MS SQL server.
start_time = (datetime.fromtimestamp(1553182159222 / 1e3))
end_time = (datetime.fromtimestamp(1553182159924/ 1e3))
run_time = end_time - start_time
Which returns:
0:00:00.702000
This is the correct math for timedelta, but I'm erroring when using run_time variable as input for SQL Server datatype TIME.
timedelta has the same string representation as used by SQL Server, so just insert it as string.
SQL:
CREATE TABLE test
(
timedelta time
)
Python:
start_time = (datetime.fromtimestamp(1553182159222 / 1e3))
end_time = (datetime.fromtimestamp(1553182159924/ 1e3))
run_time = end_time - start_time
cursor = cnxn.cursor()
cursor.execute("insert into test (timedelta) values (?)", str(run_time))
cnxn.commit()
cursor.execute("select timedelta from test")
row = cursor.fetchone()
while row:
print(str(row[0]))
row = cursor.fetchone()
Output:
00:00:00.702000

timestamp column in sqlite return string in python

i create a table with SQLite Date Browse App ...
when i want retrieve datetime value from timestamp column , SQLite return unicod type ...
this is my insert code :
def Insert(self,mode,path,vname,stime,ftime):
con = sqlite3.connect(PATH_DataBase) # #UndefinedVariable
con.execute('INSERT INTO SendList VALUES(?,?,?,?,?)',(mode,path,vname,stime,ftime))
con.commit()
con.close()
dt1 = datetime.datetime(2013,01,01,01,01,01,0)
dt2 = datetime.datetime(2015,01,01,01,01,01,0)
c = 0
for f in os.listdir('/home/abbas/test/'):
c += 1
slist.Insert(common.MODE_Bluetooth_JAVA, '/home/abbas/test/'+f,'flower'+str(c) , dt1, dt2)
and now this is my table :
but when i want compare starttime with datetime.now() python give me error :
TypeError: can't compare datetime.datetime to unicode
"SQLite does not have a storage class set aside for storing dates and/or times." Reference: https://www.sqlite.org/datatype3.html
Python's sqlite3 module offers "default adapters for the date and datetime types in the datetime module." Reference: https://docs.python.org/2/library/sqlite3.html#default-adapters-and-converters
The only catch is that you must be sure to define the columns appropriately. Example DDL:
import sqlite3
con = sqlite3.connect(PATH_DataBase, detect_types=sqlite3.PARSE_DECLTYPES)
con.execute('''create table if not exists SendList (
cid primary key,
mode text,
path text,
vname text,
starttime timestamp,
endtime timestamp);''')
con.commit()
con.close()
Any subsequent connections to insert or select data must pass sqlite3.PARSE_DECLTYPES as the value for the keyword argument (aka kwarg) detect_types. Example:
import datetime as dt
con = sqlite3.connect(PATH_DataBase, detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.cursor()
cur.execute('''select
*
from
SendList
where
starttime between ? and ?
limit 10;''',
(dt.datetime(2013,1,1,0,0,0), dt.datetime(2014,12,31,23,59,59)))
results = cur.fetchall()

SQLite received a naive datetime while time zone support is active

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)

Categories