I have a unique situation where I am in need of pulling the current time from an SQL server and using that value in my python program as a string. I don't know how to pull it down to print or assign to a variable.
Example:
do stuff...
var = mySQL server datetime <---- How do i do that part ??
print var;
do more stuff...
You can use a library like _mysql to connect to the server then something like this should work.
import _mysql
db = _mysql.connect(host="localhost",user="user", passwd="pass", db="db")
db.execute('select now()')
r = db.store_result()
time_var = r[0][0]
print time_var
In most cases your safest bet is to work with GMT and calculate the offset wherever you need it. If you need to get the date from MySQL however it should look similar to this:
import MySQLdb
db = MySQLdb.connect(host="localhost", user="root", passwd="")
c = db.cursor()
c.execute("SELECT NOW()")
current_time = c.fetchone()
the current_time will be a datetime.datetime object and you can treat it any way you like from there
Related
I have a personal project to create a Telegram bot using python. What I want is to reply to any question with a dynamic answer generate from a database query. I don't want to create data query for every request from bot, so my idea is to generate a set of data (data frame) and then bot can take the answer from there. To generate the data frame, I want to schedule/reload the part of the querying script for every x minutes. My goal is to create Python script which can reload only on querying data without reloading the whole script. is there any ways to do this?
Sample code:
tt = datetime.now()
dsn_tns = cx_Oracle.makedsn(----)
conn = cx_Oracle.connect(user=----, password=----, dsn=dsn_tns)
cursor = conn.cursor()
sql = ("""select *
from TABLE
WHERE REPORTDATE > to_date(:tt,'DD-MM-YYYY HH24:MI:SS')""")
param = {"tt": tt}
data = psql.read_sql(sql,conn)#,params = param)
conn.close()
x = 2314 #value from question via bot
answer = data[(data['number'] == x))]
The part I want to reload regularly is from tt until conn.close().
I'm not sure why you don't want to rerun the query for each bot request, this would make more sense. It seems like you could also have missing data if you do not update your data for each bot request.
However, you can just wrap the code between tt and conn.close() in a function which you can set to run periodically.
def update_data()
global data
tt = datetime.now()
dsn_tns = cx_Oracle.makedsn(----)
conn = cx_Oracle.connect(user=----, password=----, dsn=dsn_tns)
cursor = conn.cursor()
sql = ("""select *
from TABLE
WHERE REPORTDATE > to_date(:tt,'DD-MM-YYYY HH24:MI:SS')""")
param = {"tt": tt}
data = psql.read_sql(sql,conn)#,params = param)
conn.close()
value_date = (pd.to_datetime('30-Oct-2019').strftime('%d-%b-%Y')).upper()
iss_cnxn = pyodbc.connect('driver={SQL Server Native Client 11.0};'
'server=abc;'
'database=xyz;'
'trusted_connection=yes')
sql_query = ' '.join(f"""select
xxx as x,
yyy as y,
zzz as z,
from dbo.abcd P WITH(NOLOCK)
where filedate = '{value_date}'""".split())
What is the best way to determine the database based on the ‘filedate’ that we are querying? In the example I have hardcoded the value_date as 30th Oct 2019 but we will pass the date parameter later. Is there any function or something to switch the database based on filedate ? There should be some connection between the filedate and switching the database. Please suggest.
You can use a simple if statement to modify the db name and use string formatting to pass the correct db name to your connection. For example if the query_date is in the future, use db1, else use db2. Change datetime.now() to whatever date you want.
from datetime import datetime
if query_date > datetime.now():
db = 'db1'
else:
db = 'db2'
iss_cnxn = pyodbc.connect('driver={SQL Server Native Client 11.0};'
'server=abc;'
'database={};'.format(db)
'trusted_connection=yes')
You could pass the data in a create_db function.
def create_db_conn(value_date):
if value_date == 'xyz':
db = 'db1'
else:
db = 'db2'
iss_cnxn = pyodbc.connect('driver={SQL Server Native Client 11.0};'
'server=abc;'
'database={};'.format(db)
'trusted_connection=yes')
return iss_cnxn
This will make your connection dynamic according to value_date. You can write another function to close this connection as well.
I'm writing a simple script that checks if user account is about to expire. I'm having a problem with an UPDATE query - it doesn't update, basically. All examples I've found on the internet seem to use tuples to update rows, however my case requires parameters to be apart from each other.
I'm completely new to Python (I started literally yesterday). My database is MySQL (almost all examples on the web use SQLite) and I can't change that. I use Python 3 and the server is running on Ubuntu 18.04. I tried replacing %s with ? or :variable. I also tried insecure way of doing this (SQL Injection vulnerable) and it didn't work either.
This is my current code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import mysql.connector
from mysql.connector import Error
import datetime
try:
mydb = mysql.connector.connect(
host="localhost",
user="rootery-root",
passwd="example",
database="playground"
)
sqlCursor = mydb.cursor()
sqlCursor.execute("SELECT id, email, last_email_date FROM users WHERE soon_expires = 1")
sqlResult = sqlCursor.fetchall()
setLastMailCmd = """UPDATE users SET last_email_date =%s WHERE id =%s"""
today = datetime.date.today()
for i in range(0, len(sqlResult)):
id = sqlResult[i][0]
email = sqlResult[i][1]
lastemaildate = sqlResult[i][2]
daydiff = lastemaildate - today
setLastMail = sqlCursor.execute(setLastMailCmd, (id, today))
if daydiff.days >= 30:
print "Sending mail and updating \"last_email_date\"."
setLastMail
else:
print "%s already received an e-mail this month - ignored." % email
setLastMail # debugging purposes
except mysql.connector.Error as error:
print("SQL connection error.".format(error))
finally:
if (mydb.is_connected()):
sqlCursor.close()
mydb.close()
print("Disconnected from database.")
print(today)
I expected it to update my table with data provided by the for loop, however it does nothing at all.
Try using functions more. You put everything in one place and it's not easy to debug.
Your problem is the way you use setLastMail # debugging purposes. It does nothing.
What would be better:
mydb = mysql.connector.connect(
host="localhost",
user="rootery-root",
passwd="example",
database="playground"
)
sqlCursor = mydb.cursor()
def set_last_email(id):
stmt = """UPDATE users SET last_email_date =%s WHERE id =%s"""
today = datetime.date.today()
sqlCursor.execute(stmt, (id, today))
And then just execute your set_last_email(id).
Remember to make cursor global, otherwise it won't be available in your function. Or acquire it directly in your function from global connection.
That's of course a dummy example, but you need to start somewhere :)
I've been stuck for a few days trying to run some code in MySQL to fill a database that I have already created. Initially upon running I got the error 1251 :
"Client does not support authentication protocol requested by server; consider upgrading MySQL client". In the MySQL documentation and stackoverflow answers I found, I was led to change the default insecureAuth setting from the default false to true. Here is the code I am currently using...
import datetime
import MySQLdb as mdb
from math import ceil
def obtain_btc():
now = datetime.datetime.utcnow()
symbols = ['BTC', 'Crypto', 'Bitcoin', 'No Sector', 'USD', now, now]
return symbols
def insert_btc_symbols(symbols, insecureAuth):
db_host = 'localhost'
db_user = 'natrob'
db_pass = '**********'
db_name = 'securities_master'
con = mdb.connect(host=db_host,user=db_user,passwd=db_pass,db=db_name,{insecureAuth:true})
column_str = "ticker, instrument, name, sector, currency, created_date, last_updated_date"
insert_str = (("%s, ")*7)[:2]
final_str = ("INSERT INTO symbols (%s) VALUES (%s)" % (column_str,insert_str))
print (final_str,len(symbols))
with con:
cur = con.cursor()
for i in range(0,int(ceil(len(symbols)/100.0))):
cur.executemany(final_str,symbols[i*100:(i+1)*100-1])
if __name__ == "__main__":
symbols = obtain_btc()
insert_btc_symbols(symbols)
I recently have gotten the error: "non-keyword arg after keyword arg". I've tried to switch the order to no avail, which leads me to believe that I may not be changing the default setting correctly. Any help or advice is appreciated. Thank you.
The issue looks like is coming from {insecureAuth:true} where it is not a keyword argument. ie var=value. I'm not familiar with the library but if that is a keyword then you should be able to set it as a keyword or pass it with **
con = mdb.connect(host=db_host,user=db_user,passwd=db_pass,db=db_name,insecureAuth=True)
or
con = mdb.connect(host=db_host,user=db_user,passwd=db_pass,db=db_name,**{insecureAuth:true})
I managed to get the section of code working by getting the public key for the password and using that in place of the normal password. This was in lieu of using the insecureAuth parameters.
I'm new to mySQL and Python.
I have code to insert data from Python into mySQL,
conn = MySQLdb.connect(host="localhost", user="root", passwd="kokoblack", db="mydb")
for i in range(0,len(allnames)):
try:
query = "INSERT INTO resumes (applicant, jobtitle, lastworkdate, lastupdate, url) values ("
query = query + "'"+allnames[i]+"'," +"'"+alltitles[i]+"',"+ "'"+alldates[i]+"'," + "'"+allupdates[i]+"'," + "'"+alllinks[i]+"')"
x = conn.cursor()
x.execute(query)
row = x.fetchall()
except:
print "error"
It seems to be working fine, because "error" never appears. Instead, many rows of "1L" appear in my Python shell. However, when I go to MySQL, the "resumes" table in "mydb" remains completely empty.
I have no idea what could be wrong, could it be that I am not connected to MySQL's server properly when I'm viewing the table in MySQL? Help please.
(I only use import MySQLdb, is that enough?)
use commit to commit the changes that you have done
MySQLdb has autocommit off by default, which may be confusing at first
You could do commit like this
conn.commit()
or
conn.autocommit(True) Right after the connection is created with the DB