inserting date time with microsecond into SQL Server from python - python

Below code works perfectly:
import pypyodbc
import datetime
connection = pypyodbc.connect('Driver={SQL Server};'
'Server=some_server;'
'Database=some_db')
cur = connection.cursor()
some_time = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
query = "insert into table_a (date_created) values ('"+some_time+"')"
cur.execute(query)
connection.commit()
connection.close()
But if I change (adding microseconds to date)
some_time = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
it generates error:
DataError: ('22007', '[22007] [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting date and/or time from character string.')
date_created column is of datetime type and does display microseconds.
Any thoughts?

SQL Server datetime columns are only able to store fractional seconds to millisecond precision (3 decimal places). When you do
some_time = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
you get a string formatted to the precision of Python's datetime, which is microseconds (6 decimal places)
>>> some_time
'2018-09-28 16:38:14.344801'
and SQL server doesn't like the extra three decimal places.
The solution is to not format the datetime as a string, just pass the datetime value itself in a proper parameterized query
query = "insert into table_a (date_created) values (?)"
params = (datetime.datetime.utcnow(), )
cur.execute(query, params)

Related

SQL DATABASE datetime date query

Getting error for below how to put date in variable for sql query?
for symbol in symbolist:
datereplace1 = '2022-04-03 00:00:00'
datereplace2 = '2022-04-03 00:00:00'
query=(f"""DELETE FROM {symbol} WHERE Time >=%s AND Time <%s""", ) #we can also delete older than x days by writing thisWHERE col <= date('now', '-10 day')
cursor.execute(query, (datereplace1,datereplace2))
test.commit()
cursor.execute(query, (datereplace1,datereplace2))
TypeError: argument 1 must be str, not tuple

Join AMAZON.DATE and AMAZON.TIME into sql DATETIME in python

I have a python code which gets following two parameters: AMAZON.DATE and AMAZON.TIME (format definition here):
import pymysql
def func(date, start_time):
conn = pymysql.connect(hostname, user=username,
passwd=password, db=database, connect_timeout=5)
cur = conn.cursor()
# SQL statement here
Now what I want to do is join these two date and time types and insert them as a sql DATETIME type. So the insert statement should be like - INSERT INTO table1 VALUES (date_time);. What I am having difficulty in is joining the two Amazon types and forming sql DATETIME type. How can I do that?
I would suggest you to convert AMAZON.DATE and AMAZON.TIME into datetime objects and then simply use
datetime.datetime.combine(datetime.date(2011, 01, 01), datetime.time(10, 23))
For example -
import datetime
date_object = datetime.datetime.strptime('2015-06-07T', '%Y-%M-%dT').date()
time_object = datetime.datetime.strptime('04:00','%H:%M').time()
date_obj_final = datetime.datetime.combine(date_object, time_object)
#output
2015-01-07
04:00:00
2015-01-07 04:00:00
Let me know,if it works !

Parameterize a quoted string in Python's SQL DBI

I am using pg8000 to connect to a PostgreSQL database via Python. I would like to be able to send in dates as parameters via the cursor.execute method:
def info_by_month(cursor, year, month):
query = """
SELECT *
FROM info
WHERE date_trunc('month', info.created_at) =
date_trunc('month', '%s-%s-01')
"""
cursor.execute(query, (year, month))
return cursor
This will raise the error: InterfaceError: '%s' not supported in a quoted string within the query string. It's possible to use Python's string formatting to insert the date in there. The use of the string formatting mini language provides a measure of data validation to prevent SQL injection attacks, but it's still pretty ugly.
def info_by_month(cursor, year, month):
query = """
SELECT *
FROM info
WHERE date_trunc('month', info.created_at) =
date_trunc('month', '{:04}-{:02}-01')
""".format(year, month)
cursor.execute(query)
return cursor
How do I sent a quoted string into the cursor.execute method?
Do the format ahead of time, and then pass the resulting string into execute. That way you avoid the SQL injection potential, but still get the formatting you want.
e.g. the query becomes:
query = """
SELECT *
FROM info
WHERE date_trunc('month', info.created_at) =
date_trunc('month', %s)"""
And then the format and execute becomes:
dateStr = "{:04}-{:02}-01".format(year, month)
cursor.execute(query, dateStr)
I use psycopg2, but it appears pg8000 adheres to the same DBI standard, so I would expect this to work in pg8000, too.
It's possible to do this via concatenation, to the detriment of readability.
query = """
SELECT *
FROM info
WHERE date_trunc('month', info.created_at) =
date_trunc('month', %s || '-' || %s || '-01')
"""
cursor.execute(query, (year, month))

ValueError when querying dates with SQLite

A simple example:
import sqlite3, datetime, csv
import pandas.io.sql as sql
from dateutil.parser import parse
my_db = 'test_db.db'
connection=sqlite3.connect(my_db,detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cursor = connection.cursor()
cursor.execute('''CREATE TABLE test_table (Id INTEGER PRIMARY KEY, Date DATE);''')
date_str = '1/1/2011'
date_parsed = parse(date_str)
cursor.execute('INSERT into test_table (Id, Date) values(?,?)',(1,date_parsed))
cursor.execute('SELECT * FROM test_table')
yields:
ValueError: invalid literal for int() with base 10: '01 00:00:00'
I'm simply trying to have the SQL db return my dates in datetime format so I can then perform filtered queries on them.
I've already read this related post for reference:
SQLite date storage and conversion
Inside your CREATE TABLE, you're using Date DATE
CREATE TABLE test_table (Id INTEGER PRIMARY KEY, Date DATE)
The problem with this is that that tries to map to datetime.date which your format isn't, if you change your format to use a TIMESTAMP, then it works correctly and tries to make it a datetime.datetime...
CREATE TABLE test_table (Id INTEGER PRIMARY KEY, Date TIMESTAMP)

Inserting a Python datetime.datetime object into MySQL

I have a date column in a MySQL table. I want to insert a datetime.datetime() object into this column. What should I be using in the execute statement?
I have tried:
now = datetime.datetime(2009,5,5)
cursor.execute("INSERT INTO table
(name, id, datecolumn) VALUES (%s, %s
, %s)",("name", 4,now))
I am getting an error as: "TypeError: not all arguments converted during string formatting"
What should I use instead of %s?
For a time field, use:
import time
time.strftime('%Y-%m-%d %H:%M:%S')
I think strftime also applies to datetime.
You are most likely getting the TypeError because you need quotes around the datecolumn value.
Try:
now = datetime.datetime(2009, 5, 5)
cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s, '%s')",
("name", 4, now))
With regards to the format, I had success with the above command (which includes the milliseconds) and with:
now.strftime('%Y-%m-%d %H:%M:%S')
Hope this helps.
Try using now.date() to get a Date object rather than a DateTime.
If that doesn't work, then converting that to a string should work:
now = datetime.datetime(2009,5,5)
str_now = now.date().isoformat()
cursor.execute('INSERT INTO table (name, id, datecolumn) VALUES (%s,%s,%s)', ('name',4,str_now))
Use Python method datetime.strftime(format), where format = '%Y-%m-%d %H:%M:%S'.
import datetime
now = datetime.datetime.utcnow()
cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s, %s)",
("name", 4, now.strftime('%Y-%m-%d %H:%M:%S')))
Timezones
If timezones are a concern, the MySQL timezone can be set for UTC as follows:
cursor.execute("SET time_zone = '+00:00'")
And the timezone can be set in Python:
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
MySQL Documentation
MySQL recognizes DATETIME and TIMESTAMP values in these formats:
As a string in either 'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD HH:MM:SS'
format. A “relaxed” syntax is permitted here, too: Any punctuation
character may be used as the delimiter between date parts or time
parts. For example, '2012-12-31 11:30:45', '2012^12^31 11+30+45',
'2012/12/31 11*30*45', and '2012#12#31 11^30^45' are equivalent.
The only delimiter recognized between a date and time part and a
fractional seconds part is the decimal point.
The date and time parts can be separated by T rather than a space. For
example, '2012-12-31 11:30:45' '2012-12-31T11:30:45' are equivalent.
As a string with no delimiters in either 'YYYYMMDDHHMMSS' or
'YYMMDDHHMMSS' format, provided that the string makes sense as a date.
For example, '20070523091528' and '070523091528' are interpreted as
'2007-05-23 09:15:28', but '071122129015' is illegal (it has a
nonsensical minute part) and becomes '0000-00-00 00:00:00'.
As a number in either YYYYMMDDHHMMSS or YYMMDDHHMMSS format, provided
that the number makes sense as a date. For example, 19830905132800 and
830905132800 are interpreted as '1983-09-05 13:28:00'.
What database are you connecting to? I know Oracle can be picky about date formats and likes ISO 8601 format.
**Note: Oops, I just read you are on MySQL. Just format the date and try it as a separate direct SQL call to test.
In Python, you can get an ISO date like
now.isoformat()
For instance, Oracle likes dates like
insert into x values(99, '31-may-09');
Depending on your database, if it is Oracle you might need to TO_DATE it:
insert into x
values(99, to_date('2009/05/31:12:00:00AM', 'yyyy/mm/dd:hh:mi:ssam'));
The general usage of TO_DATE is:
TO_DATE(<string>, '<format>')
If using another database (I saw the cursor and thought Oracle; I could be wrong) then check their date format tools. For MySQL it is DATE_FORMAT() and SQL Server it is CONVERT.
Also using a tool like SQLAlchemy will remove differences like these and make your life easy.
If you're just using a python datetime.date (not a full datetime.datetime), just cast the date as a string. This is very simple and works for me (mysql, python 2.7, Ubuntu). The column published_date is a MySQL date field, the python variable publish_date is datetime.date.
# make the record for the passed link info
sql_stmt = "INSERT INTO snippet_links (" + \
"link_headline, link_url, published_date, author, source, coco_id, link_id)" + \
"VALUES(%s, %s, %s, %s, %s, %s, %s) ;"
sql_data = ( title, link, str(publish_date), \
author, posted_by, \
str(coco_id), str(link_id) )
try:
dbc.execute(sql_stmt, sql_data )
except Exception, e:
...
dt= datetime.now()
query = """INSERT INTO table1(python_Date_col)
VALUES (%s)
"""
conn = ...... # Connection creating process
cur = conn.cursor()
cur.execute(query,(dt))
Above code will fail as "datetime.now()" produces "datetime.datetime(2014, 2, 11, 1, 16)" as a parameter value to insert statement.
Use the following method to capture the datetime which gives string value.
dt= datetime.now().strftime("%Y%m%d%H%M%S")
I was able to successfully run the code after the change...
for example date is 5/5/22 convert it into mysql date format 2022-05-05 to insert record in mysql database
%m month
%d date
%Y Year of 4 digits
%y 2 digits
Code Below:
from datetime import datetime
now='5/5/22'
print("Before", now)
now= datetime.strptime(dob,'%m/%d/%y').strftime('%Y-%m-%d')
print("After", now)
cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s, %s)",(name, 4,now))
Output:
Before 5/5/22
After 2022-05-05
(mysql format you can easily insert into database)
when iserting into t-sql
this fails:
select CONVERT(datetime,'2019-09-13 09:04:35.823312',21)
this works:
select CONVERT(datetime,'2019-09-13 09:04:35.823',21)
easy way:
regexp = re.compile(r'\.(\d{6})')
def to_splunk_iso(dt):
"""Converts the datetime object to Splunk isoformat string."""
# 6-digits string.
microseconds = regexp.search(dt).group(1)
return regexp.sub('.%d' % round(float(microseconds) / 1000), dt)

Categories