Insert into mysql python - not working - python

I have created the following table in MySQL
create table DT (Date varchar(20), Time varchar(20))
I am using the following python code to insert into mysql. I am not getting any error nor the date and time is getting written into mysql.
import mysql.connector
from datetime import datetime
conn = mysql.connector.connect(host = 'localhost', database = 'mydatabase', user = 'root', password = '')
cursor = conn.cursor()
i = datetime.now()
xdate = i.strftime('%Y-%m-%d')
xtime = i.strftime('%H-%M-%S')
sqql = 'insert into DT (Date, Time) values (%s,%s);'
cursor.execute(sqql, xdate, xtime)
conn.commit()
conn.close()
I am not getting any error nor getting the date and time inserted into mysql. However when I directly do the insert in mysql it works..
insert into DT (Date, Time) values ('2017-02-06', '19-54-36');
Not sure how to resolve? Can someone help?

You are not passing the query parameters correctly, put them into a tuple, replace:
cursor.execute(sqql, xdate, xtime)
with:
cursor.execute(sqql, (xdate, xtime))

According to this example and the documentation, the method cursor.execute() takes a string query as first parameter, and the second parameter is a tuple or a dictionary that contains the values of that query. So you should call the method this way:
cursor.execute(sqql, (xdate, xtime))
In case you are using xdate and xtime just in this invocation, you can even simplify this call by:
cursor.execute(sqql, (i.strftime('%Y-%m-%d'), i.strftime('%H-%M-%S')))
In addition, you can also use a dictionary in order to improve the readability of the code:
sqql = 'insert into DT (Date, Time) values (%(xdate)s, %(xtime)s);'
cursor.execute(sqql, {'xdate': `xdate`, 'xtime`: xtime})

Related

Psycopg2/PostgreSQL 11.9: Syntax error at or near "::" when performing string->date type cast

I am using psycopg2 to create a table partition and insert some rows into this newly created partition. The table is RANGE partitioned on a date type column.
Psycopg2 code:
conn = connect_db()
cursor = conn.cursor()
sysdate = datetime.now().date()
sysdate_str = sysdate.strftime('%Y%m%d')
schema_name = "schema_name"
table_name = "transaction_log"
# Add partition if not exists for current day
sql_add_partition = sql.SQL("""
CREATE TABLE IF NOT EXISTS {table_partition}
PARTITION of {table}
FOR VALUES FROM (%(sysdate)s) TO (maxvalue);
""").format(table = sql.Identifier(schema_name, table_name), table_partition = sql.Identifier(schema_name, f'{table_name}_{sysdate_str}'))
print(cursor.mogrify(sql_add_partition, {'sysdate': dt.date(2015,6,30)}))
cursor.execute(sql_add_partition, {'sysdate': sysdate})
Formatted output of cursor.mogrify():
CREATE TABLE IF NOT EXISTS "schema_name"."transaction_log_20211001"
PARTITION of "schema_name"."transaction_log"
FOR VALUES FROM ('2021-10-01'::date) TO (maxvalue);
Error received:
ERROR: syntax error at or near "::"
LINE 3: for values FROM ('2021-10-01'::date) TO (maxvalue);
Interestingly enough, psycopg2 appears to be attempting to cast the string '2021-10-01' to a date object with the "::date" syntax, and according to the postgreSQL documentation, this appears to be valid (although there are no explicit examples given in the docs), however executing the statement with both pyscopg2 and in a postgreSQL query editor yields this syntax error. However, executing the following statement in a postgreSQL SQL editor is successful:
CREATE TABLE IF NOT EXISTS "schema_name"."transaction_log_20211001"
PARTITION of "schema_name"."transaction_log"
FOR VALUES FROM ('2021-10-01') TO (maxvalue);
Any ideas on how to get psycopg2 to format the query correctly?
To follow up on #LaurenzAlbe comment:
sql_add_partition = sql.SQL("""
CREATE TABLE IF NOT EXISTS {table_partition}
PARTITION of {table}
FOR VALUES FROM (%(sysdate)s) TO (maxvalue);
""").format(table = sql.Identifier(schema_name, table_name), table_partition = sql.Identifier(schema_name, f'{table_name}_{sysdate_str}'))
print(cursor.mogrify(sql_add_partition, {'sysdate': '2021-10-01'}))
#OR
sql_add_partition = sql.SQL("""
CREATE TABLE IF NOT EXISTS {table_partition}
PARTITION of {table}
FOR VALUES FROM ({sysdate}) TO (maxvalue);
""").format(table = sql.Identifier(schema_name, table_name),
table_partition = sql.Identifier(schema_name, f'{table_name}_{sysdate_str}'),
sysdate=sql.Literal('2021-10-01'))
print(cursor.mogrify(sql_add_partition))
#Formatted as
CREATE TABLE IF NOT EXISTS "schema_name"."transaction_log_20211001"
PARTITION of "schema_name"."transaction_log"
FOR VALUES FROM ('2021-10-01') TO (maxvalue);
Pass the date in as a literal value instead of a date object. psycopg2 does automatic adaptation of date(time) objects to Postgres date/timestamp types(Datetime adaptation) which is what is biting you.
UPDATE
Per my comment, the reason why it needs to be a literal is explained here Create Table:
Each of the values specified in the partition_bound_spec is a literal, NULL, MINVALUE, or MAXVALUE. Each literal value must be either a numeric constant that is coercible to the corresponding partition key column's type, or a string literal that is valid input for that type.

How to update an integer value in an SQL record?

I'm pretty new to SQL and the Sqlite3 module and I want to edit the timestamps of all the records in my DB randomly.
import sqlite3
from time import time
import random
conn = sqlite3.connect('database.db')
c = sqlite3.Cursor(conn)
ts_new = round(time())
ts_old = 1537828957
difference = ts_new - ts_old
for i in range(1,309):
#getting a new, random timestamp
new_ts = ts_old + random.randint(0, difference)
t = (new_ts, i)
c.executemany("UPDATE questions SET timestamp = (?) WHERE rowid = (?)", t)
#conn.commit()
When run, I get a ValueError: parameters are of unsupported type.
To add the timestamp value originally I set t to a tuple and the current UNIX timestamp as the first value of a it e.g (1537828957, ). Is this error displaying because I've used two (?) unlike the single one I used in the statement to add the timestamps to begin with?
You're using executemany instead of execute. executemany takes an iterator of tuples and executes the query for each tuple.
You want to use execute instead, it executes the query once using your tuple.
c.execute('UPDATE questions SET timestamp = (?) where rowid = (?)', t)

Store date-time as integer in sqlite

I am trying to convert a date-time string value into an integer when I store it in a sqlite table. I am using Python (Flask). I am getting an 'Error in insert operation' with the following query.
Any ideas?
with sql.connect("flaskjournal.db") as con:
cur = con.cursor()
t_i = strftime('%s','time_in')
cur.execute("INSERT INTO entries (beach, board, swell, wind, score, notes, time_in)
VALUES (?,?,?,?,?,?,?)",(beach, board, swell, wind, score, notes, t_i))
con.commit()
msg = "Record successfully added"
You can use the timestamp instead.
import time
from datetime import datetime
timestamp = int(time.mktime(datetime_object.timetuple())
Make t_i insert a unix timestamp via your create table schema. so you don't need to muck with it from python.
sqlite> create table t1 (
...> id integer primary key,
...> time t_i default (strftime('%s', 'now')),
...> txt text);

Rewriting datetime in mysql

I'm having some trouble modifying a sql table that contains a date.
This is the code I'm running:
import pymysql
cnx=pymysql.connect(dbstuff)
cursor=cnx.cursor()
cursor.execute("SELECT * FROM devices ORDER BY ip_addr,Port ASC")
results=cursor.fetchall()
lst = [(i,)+line[1:] for i, line in enumerate(results, 1)]
values = ', '.join(map(str,lst))
query="DELETE FROM devices; INSERT INTO devices VALUES {}".format(values)
query = query.replace("None","NULL")
cursor.execute(query)
cnx.commit()
cnx.close()
If the date column in sql is NULL, this runs without a problem. If there is a date inserted into the field, I get the following error:
"FUNCTION datetime.datetime does not exist."
When I look at the results of the sql select query, the date column value is converted to the following:
datetime.datetime(2016, 8, 16, 11, 24, 4)
I assume this is a python thing and not a sql thing. I haven't been to find anyway to convert this to a format sql would understand.
For datetime values you may use this:
your_datetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
This variable will hold a string value like this:
2018-05-06 21:14:37
And then use the following SQL command:
"INSERT INTO your_table (your_datetime_column) VALUES (str_to_date(\'%s\', '%%Y-%%m-%%d %%H:%%i:%%s'))" % (your_datetime)
DO NOT USE FOLLOWING - it won't work with the .format() method:
"INSERT INTO your_table (your_datetime_column) VALUES ({0})".format (your_datetime)
Calling the str function of the datetime.datetime object will convert it to the string format required by SQL. It is currently trying to insert a python object.
Simply wrap your object like this:
dt = str(my_datetime_object)
This error is raised when you pass invalid format date string in SQL query. Even a space in '2018-05-01 11:02:02 ' can cause this error. The best way to get rid of it is to avoid string formatting while making sql queries.
c=db.cursor()
c.execute("INSERT INTO devices VALUES(%s,%s,%s)",(value1,value2,value3))
c.close()
If you are unknown that how many values will have then, you have to generate (%s,%s...) dynamically.
import pymysql
cnx=py
mysql.connect(dbstuff)
cursor=cnx.cursor()
cursor.execute("SELECT * FROM devices ORDER BY ip_addr,Port ASC")
results=cursor.fetchall()
lst = [(i,)+line[1:] for i, line in enumerate(results, 1)]
formatt=','.join(['%s']*len(lst))
query="INSERT INTO devices VALUES (%s)"%formatt
cursor.execute(query,lst)
cnx.commit()
cnx.close()

can a return value of a function be passed in the where clause

I have a python code that displays a list of station ID and air temperature for certain number of days. In the code below I have passed the dates as a list. But that is cumbersome coding since I have to write all the dates in the list. Is there any way wherein I can pass the return value of a function to the where clause. I want to know how a range of values with start and end date can be passed in the query below. Following is the code snippet:
import MySQLdb
import os,sys
import datetime
path="C:/Python27/"
conn = MySQLdb.connect (host = "localhost",user = "root", passwd = "CIMIS",db = "cimis")
c = conn.cursor()
message = """select stationId,Date,airTemperature from cimishourly where stationId in (2,7) and Date in ('2016,01,01','2016,01,04') """
c.execute(message,)
result=c.fetchall()
for row in result:
print(row)
conn.commit()
c.close()
Yes you can substitute the return value of a function in your query. Because message is just a string you can concatenate it like you would any other string.
message = """select stationId,Date,airTemperature from cimishourly where stationId in (2,7) and Date in (""" + functionToGetDates() + """)"""
The parentheses can be formatted in the function or in the original string like I chose to do.

Categories

Resources