I am working on my first Python script to check email then parse out some data then insert into a Microsoft sql database. I am having problems with how to insert the saved variable t.
import imaplib
import email
import re
import _mssql
m = imaplib.IMAP4_SSL("imap.gmail.com", 993)
m.login("username","password$")
m.select('"Fire_Dispatch"')
result, data = m.search(None, "ALL") # search all email and return uids
if result == 'OK':
for num in data[0].split():
result, data = m.fetch(num,"(BODY[TEXT])")
if result == 'OK':
email_message = email.message_from_string(data[0] [1].decode('utf-8')) # raw email text including headers
p = str(email_message)
a = re.search("ALLCFD(.*)",p)
t = (a.groups(1))
print (t)
conn = _mssql.connect(server='server', user='username', password='password', database='CFD_Calls')
conn.execute_non_query("INSERT INTO calls (call_date_time,call)VALUES('3',t)")
m.close()
m.logout()
You'll need to provide the t variable into the sql execution. One way to do this:
conn.execute_non_query("INSERT INTO calls (call_date_time,call) VALUES('3',?)", (t,))
I'm assuming t will be a string. Note that when provided to the sql command, the variable is enclosed in a tuple. This is because the command expects the argument to be a sequence.
Related
I want to check if the input password is the same as that stored in the database but when I use bcrypt.checkpw() it returns an error saying that it expects a string or byte because the SQL query returns a tuple. I can't find a way to convert the database response to a byte from a tuple to make it compatible.
sql = ''' SELECT password FROM user_data WHERE username=? '''
username = input('Input username: ')
password = bytes(input('Input Password: '), encoding='utf-8')
cur = conn.cursor()
cur.execute(sql, (username,))
rows = cur.fetchall()
for row in rows:
if bcrypt.checkpw(password, row):
details = (user_id, username, password)
print('logged in')
return details
break
Simply adding row[0] within the function solves the problem as it returns the first (and only) value inside the tuple.
Treat it like a list in other words
Extracting the a value from a tuple when the other values are unused
I'm setting up a program that extracts the date, sender, subject and body of emails in my outlook. However, when I run the code it gives me the below error:
Traceback (most recent call last):
File "C:\Users\zaballgl\Documents\Adhoc\2019\April\ETL_MetricsEmailOutlook.py", line 83, in <module>
cursor.execute("INSERT INTO dbo.BSO_metricsEmailReports([Start_Date],[Name],[Subject],[Body])values(?,?,?,?)",row['Start_Date'],row['Name'],row['Subject'],row['Body'])
pyodbc.ProgrammingError: ('Invalid parameter type. param-index=1 param-type=CDispatch', 'HY105')
This is my code for extracting data from my outlook:
import win32com.client
import pandas as pd
import datetime
import numpy as np
import pyodbc
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders('email#outlook.com').Folders('Inbox')
messages = inbox.Items
message = messages.GetFirst()
rec_time = message.CreationTime
body_content = message.body
subj_line = message.subject
sender = message.Sender
year=[]
month=[]
day=[]
hour=[]
minute=[]
subject=[]
sender=[]
body = []
while message:
###This iterates every format of the message.CreationTime and append them to the list above
year.append(message.CreationTime.year)
month.append(message.CreationTime.month)
day.append(message.CreationTime.day)
hour.append(message.CreationTime.hour)
minute.append(message.CreationTime.minute)
## Iterates every subject and append them to the subject variable list
subject.append(message.subject)
## Iterates every sender name and append them to the sender variable list
sender.append(message.Sender)
## Iterates every sender name and append them to the sender variable list
body.append(message.body)
## Goes to the next email
message = messages.GetNext()
## This saves all the information to a context manager
#------COLUMNS FOR THE TABLE---------------#
#StartDate
date = pd.DataFrame({'year':year,'month':month,'day':day,'hour':hour,'minute':minute}) # Had to do this to bypass this error: ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=True
startDate = pd.to_datetime(date) # Using the above variable this converts this to dtype: datetime64[ns]
#Subject
subject = pd.Series(subject) # just a series of subject data
#Sender
sender = pd.Series(sender) # just a series of sender data
#Body
body = pd.Series(body) # just a series of sender data
df2 = pd.DataFrame({'Start_Date':startDate,'Name':sender, 'Subject': subject, 'Body':body})
And this is my code to transfer them to my MS SQL:
connStr = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server}; Server=someservername;DATABASE=somedatabase;UID=someID;PWD=somepassword#')
cursor = connStr.cursor()
deleteTable = "DELETE FROM dbo.BSO_metricsEmailReports"
cursor.execute(deleteTable)
for index,row in df2.iterrows():
cursor.execute("INSERT INTO dbo.BSO_metricsEmailReports([Start_Date], [Name],[Subject], [Body])values(?,?,?,?)",row['Start_Date'],row['Name'],row['Subject'],row['Body'] )
connStr.commit()
cursor.close()
connStr.close()
They would be sent to a table in my MS SQL 2014 with the below design:
**Column Name** | **Data Type**
Start_Date | datetime
Name | nchar(300)
Subject | nchar(300)
Body | nchar(300)
I'd check the execute line...
I use the ? for each parameter in the query and set it up:
sql_rollup =
'''
SELECT ID,FIRSTNAME, LASTNAME, .USERNAME, numSessions
FROM SESSION INNER JOIN
PERSONNEL ON SESSION.ID = PERSONNEL.ID
WHERE (SessionStartDT between ? AND ?) AND (SiteID = ?)
'''
Then I execute the above like this:
con = pyodbc.connect(
Trusted_connection='Yes',
Driver='{SQL Server}',
Server=myConfig["database"]["hostname"] + ',' + myConfig["database"]["port"],
Database=myConfig["database"]["database"]
)
con.autocommit = True
cur=con.cursor()
parms = (str(dateFirst), str(dateLast), siteID)
cur.execute(sql_rollup,parms)
Note the params is set up as a list and also (and I suspect this is where the problem lies), I convert the datatime values for dateFirst and dateLast to strings.
pyodbc doesn't understand Python objects. The database on the otherhand can automatically interpret strings and convert them into date/time values.
Does this help?
I've a problem in this SELECT:
Premise:
I made a script that create a Database with a 'Key' that is a password encrypted -> code of encrypt:
import base64
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
password_provided = "password" # input
password = password_provided.encode() # Convert in type byte
salt = b'\xaes\xff\x80\xe2| (\xfcG\xbdk\xedxb9\x15n7'
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend()
)
key = base64.urlsafe_b64encode(kdf.derive(password)) #can only use kdf once
print(key)
Now I'm trying to do an AUTH with method POST, I start trying with some SELECT for 'search' the password for the log and find a method to compare the string not encrypted with the encrypted string for login I try:
mycursor = mydb.cursor()
sql = "SELECT password FROM users WHERE password = %s", (key) #Problem!
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
print(x)
My output is :
** File "login.py", line 12, in <module>
mycursor.execute(sql)
File "/Users/jhon/prova/lib/python3.7/site-packages/mysql/connector/cursor.py", line 536, in execute
stmt = operation.encode(self._connection.python_charset)
AttributeError: 'tuple' object has no attribute 'encode'
**
I try to do "key1 = key.encode()" , but it's wrong...
Thanks to all.
This line creates a 2-tuple of a string and an int and assigns it to variable "sql":
sql = "SELECT password FROM users WHERE password = %s", (key) #Problem!
"(key)" does not produce a 1-tuple; to do that you want "(key,)". It looks like you wanted to create a 2-tuple of a string followed by a 1-tuple.
Then this line sends the 2-tuple you created as a single argument to the method being called:
mycursor.execute(sql)
If this is the library you are using, then the docstring for the function definition execute (see line 183) here...: https://github.com/mysql/mysql-connector-python/blob/master/lib/mysql/connector/cursor.py
... shows that you want to specify your query pattern fill-in values using an n-tuple as the second function argument to .execute(...). You can do that with the variadic argument operator a.k.a. sequence-unpack operator (mentioned as part of https://medium.com/understand-the-python/understanding-the-asterisk-of-python-8b9daaa4a558), or you can separate them out. So you might want code like this:
sql = "SELECT password FROM users WHERE password = %s"
values = (key,)
mycursor.execute(sql, values)
or
sql = "SELECT password FROM users WHERE password = %s", (key,)
# star operator inside function call unpacks sequence variable by one level into separate arguments.
mycursor.execute(*sql)
I have a problem where I am trying to call a specific field from the data recovered by the self.results variable from the sqlite3 login database, although I am unable to do this as I believe that the fetched data is not in an array format and therefore the system is unable to use that field, I got rid of all the " ' ", "(", ")" but I do not know what to do now to convert this text file into an array so that a field can be fetched and printed.
Could you help me?
while True:
username = self.usernameEntry.get()
password = self.passwordEntry.get()
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
findUser = ("SELECT * FROM students WHERE CardNumberID = ? AND Password = ?")
cursor.execute(findUser, [(username), (password)])
self.results = cursor.fetchone()
fetchedResults = str(self.results)
fetchedResults = fetchedResults.replace('(', '')
fetchedResults = fetchedResults.replace(')', '')
fetchedResults = fetchedResults.replace("'", '')
fetchedResults.split(',')
print(fetchedResults[2])
print(self.results)
Here are the results that I get:
The results are in an "array" format, but you then explicitly convert the whole thing to a string. Don't do that.
I am querying a Oracle database and need some special handling around one column of data that is a clob. I can read in the clobe with .read(). I'd like to write the actual value back to my array. It's a tuple so I must convert to a list, write the value, then convert back to tuple. I am getting the error message: TypeError: 'tuple' object does not support item assignment
My Code:
import cx_Oracle
# USE THIS CONNECTION STRING FOR PRODUCTION
production_username = 'username'
production_password = 'password'
con_string = '%s/%s#hostname:port/orcl' % (production_username, production_password)
con = cx_Oracle.connect(con_string)
cursor = con.cursor()
querystring = ("Select ID, Description from Table")
cursor.execute(querystring)
data = cursor.fetchall()
for currentrow in range(1, len(data)):
description= data[currentrow][1].read()
data = list(data)
data[currentrow][1] = description
data = tuple(data)
con.close()
print data
Try this way
for currentrow in data :
description= currentrow[1].read()
tupled_data= tuple([currentrow[0],description])
print tupled_data