python mysqldb, for loop not deleting records - python

Somewhere in here lies a problem. http://paste.pocoo.org/show/528559/
Somewhere between lines 32 and 37. As you can see the DELETE FROM is inside a for loop.
Running the script just makes the program go through the loop and exit, without actually removing any records.
Any help would be greatly appreciated! Thanks!
#!/usr/bin/env python
# encoding: utf-8
import os, os.path, MySQLdb, pprint, string
class MySQLclass(object):
"""Learning Classes"""
def __init__(self, db):
self.db=db
self.cursor = self.db.cursor()
def sversion(self):
self.cursor.execute ("SELECT VERSION()")
row = self.cursor.fetchone ()
server_version = "server version:", row[0]
return server_version
def getRows(self, tbl):
""" Returns the content of the table tbl """
statmt="select * from %s" % tbl
self.cursor.execute(statmt)
rows=list(self.cursor.fetchall())
return rows
def getEmailRows(self, tbl):
""" Returns the content of the table tbl """
statmt="select email from %s" % tbl
self.cursor.execute(statmt)
rows=list(self.cursor.fetchall())
return rows
def removeRow(self,tbl,record):
""" Remove specific record """
print "Removing %s from table %s" %(record,tbl)
print tbl
self.cursor.execute ("""DELETE FROM maillist_frogs where email LIKE %s""", (record,))
def main():
#####connections removed
sql_frogs = MySQLclass(conn_frogs)
sql_mailgust = MySQLclass(conn_mailgust)
frogs_emails = sql_frogs.getEmailRows ("emails")
frogs_systemcatch = sql_frogs.getEmailRows ("systemcatch")
mailgust_emails = sql_mailgust.getEmailRows ("maillist_frogs")
aa = set(mailgust_emails)
remove = aa.intersection(frogs_emails)
remove = remove.union(aa.intersection(frogs_systemcatch))
for x in remove:
x= x[0]
remove_mailgust = sql_mailgust.removeRow ("maillist_frogs",x)
conn_frogs.close ()
conn_mailgust.close ()
if __name__ == '__main__':
main()

the problem is python-msyqldb specific.:
Starting with 1.2.0, MySQLdb disables autocommit by default, as required by the DB-API standard (PEP-249). If you are using InnoDB tables or some other type of transactional table type, you'll need to do connection.commit() before closing the connection, or else none of your changes will be written to the database.
therefore, after the DELETE, you must self.db.commit

The removeRow() method does not return a value, yet remove_mailgust is expecting to receive this non-existent value.
Also, your removeRow() class method is statically fixed to only search the table maillist_frogs in its query. You should probably set the table name to accept the second parameter of the method, tbl.
Finally, your removeRow() method is comparing the value of a record (presumably, an id) using LIKE, which is typically used for more promiscuous string comparison. Is email your primary key in this table? If so, I would suggest changing it to:
self.cursor.execute ("""DELETE FROM %s where email_id = %s""", (tbl, record,))

Related

The Code is not working in jupyter and giving the error as pictured below [duplicate]

I am trying to query on a local MySQL database using Python's (3.4) MySQL module with the following code:
class databases():
def externaldatabase(self):
try:
c = mysql.connector.connect(host="127.0.0.1", user="user",
password="password", database="database")
if c.is_connected():
c.autocommit = True
return(c)
except:
return(None)
d = databases().externaldatabase()
c = d.cursor()
r = c.execute('''select * from tbl_wiki''')
print(r)
> Returns: None
As far as I can tell, the connection is successful, the database is composed of several rows but the query always returns the none type.
What instances does the MySQL execute function return None?
Query executions have no return values.
The pattern you need to follow is:
cursor creation;
cursor, execute query;
cursor, *fetch rows*;
Or in python:
c = d.cursor()
c.execute(query) # selected rows stored in cursor memory
rows = c.fetchall() # get all selected rows, as Barmar mentioned
for r in rows:
print(r)
Also some db modules allow you to iterate over the cursor using the for...in pattern, but triple-check that regarding mysql.
For my case, I return the cursor as I need the value to return a string specifically, for instance, I return the password (string) for inspect whether user used the same password twice. Here's how I did it (In my case):
def getUserPassword(metadata):
cursorObject.execute("SELECT password FROM users WHERE email=%s AND password=%s LIMIT 1", (metadata['email'], metadata['password']))
return cursorObject.fetchall()[0]['password']
Which I can easily call from another class by calling the method:
assert getUserPassword({"email" : "email", "password" : "oldpass"}) is not None
And which the getUserPassword itself is returning a string

simple CLI todo manager with sqlite3 database storing problem

I am currently trying to make a command line todo manager that will allow the user to input a task(s), remove it and list the task(s) out. From what I tried visualizing it didn't do as I thought it would, it's my first time using sqlite3.
What I am trying to achieve:
Storing the task(s) in the database which will automatically add an incrementing ID to it.
Example:
python todo.py -add do the laundry on Sunday
[in the database]
Id Task
1 do the laundry on Sunday
My code.
import sqlite3
import argparse
def parse_args():
desc = 'Todo manager for storing and removing tasks'
parser = argparse.ArgumentParser(description=desc)
parser.add_argument("-a", "--add", "-add", help="To add a new item to the list",
type=str, nargs="+")
parser.add_argument("-r", "-remove", "--remove", help="To remove an item from the list",
type=int)
parser.add_argument("-l", "-list", "--list", help="displays the tasks or task in the list",
nargs="*")
args = parser.parse_args()
return args
#staticmethod
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
def get_todo_list():
database_connection.row_factory = dict_factory
cursor = database_connection.cursor()
cursor.execute("select rowid, * FROM todo_list")
return cursor.fetchall()
def add_to_todo_list(num,task):
cursor = database_connection.cursor()
cursor.execute("INSERT INTO todo_list VALUES (?)", (str(task),))
database_connection.commit()
def remove_from_todo_list(rowid):
cursor = database_connection.cursor()
cursor.execute("DELETE FROM todo_list WHERE rowid = ?", (rowid,))
database_connection.commit()
if __name__ == '__main__':
commands = parse_args()
# Creating table for database using sqlite
database_connection = sqlite3.connect('todo_list.db')
cursor = database_connection.cursor()
cursor.execute('''CREATE TABLE if not exists todo_list(
description TEXT);''')
database_connection.commit()
if commands.add:
# Stops accepting tasks when there is a blank task as input.
if not commands.add == ' ':
add_to_todo_list(commands.add)
elif commands.remove:
remove_from_todo_list(commands.remove)
elif commands.list:
get_todo_list()
However, my database is not accepting any values when I am trying to store data. By putting Id as Id INTEGER PRIMARY KEY when creating the table i.e.
cursor.execute('''CREATE TABLE if not exists todo_list(
Id INTEGER PRIMARY KEY
description TEXT);''')
Will the Id increment as I add data to the database?
sqlite3.InterfaceError: Error binding parameter 1 - probably unsupported type.
Your inputs from argparse are coming in as str, yet you defined your column ID as an INTEGER in your db. Fix is:
cursor.execute("INSERT INTO todo_list VALUES (?,?)", (int(num), task,))
Storing the task(s) in the database which will automatically add an incrementing ID to it.
According to the sqlite docs here, defining a INTEGER PRIMARYKEY will auto-increment. Simply pass a null value to it, and sqlite takes care of the rest for you.
You have a few issues on your code when it comes to displaying and adding the tasks. First, initializing the DB:
cursor.execute(
"""CREATE TABLE if not exists todo_list(
id INTEGER PRIMARY KEY,
description TEXT);"""
)
How you had it before your post edit was fine. Then, the add_to_todo_list:
def add_to_todo_list(task):
cursor = database_connection.cursor()
cursor.execute("INSERT INTO todo_list VALUES (?,?)", (None, str(task)))
database_connection.commit()
Notice the removal of num from the functions input, and the passing of None for the column ID. Within the get_todo_list() you can fetch it more easily as so:
def get_todo_list():
cursor = database_connection.cursor()
cursor.execute("select * FROM todo_list")
return cursor.fetchall()
A fix is also needed in the way you parse your args; for commands.list you need to do the following:
elif commands.list is not None:
print(get_todo_list())
This is since commands.list will be a [] when you do app.py -list, which Python evaluates to False (empty lists are falsey). You also ought to print the contents of the function to terminal -- so don't forget that. With the edits above I can do on my terminal:
python test.py -add Random Task!
python test.py -add Hello World!
python test.py -list
[(1, "['Random', 'Task!']"), (2, "['Hello', 'World!']")]

connection returns none (pymssql) [duplicate]

I am trying to query on a local MySQL database using Python's (3.4) MySQL module with the following code:
class databases():
def externaldatabase(self):
try:
c = mysql.connector.connect(host="127.0.0.1", user="user",
password="password", database="database")
if c.is_connected():
c.autocommit = True
return(c)
except:
return(None)
d = databases().externaldatabase()
c = d.cursor()
r = c.execute('''select * from tbl_wiki''')
print(r)
> Returns: None
As far as I can tell, the connection is successful, the database is composed of several rows but the query always returns the none type.
What instances does the MySQL execute function return None?
Query executions have no return values.
The pattern you need to follow is:
cursor creation;
cursor, execute query;
cursor, *fetch rows*;
Or in python:
c = d.cursor()
c.execute(query) # selected rows stored in cursor memory
rows = c.fetchall() # get all selected rows, as Barmar mentioned
for r in rows:
print(r)
Also some db modules allow you to iterate over the cursor using the for...in pattern, but triple-check that regarding mysql.
For my case, I return the cursor as I need the value to return a string specifically, for instance, I return the password (string) for inspect whether user used the same password twice. Here's how I did it (In my case):
def getUserPassword(metadata):
cursorObject.execute("SELECT password FROM users WHERE email=%s AND password=%s LIMIT 1", (metadata['email'], metadata['password']))
return cursorObject.fetchall()[0]['password']
Which I can easily call from another class by calling the method:
assert getUserPassword({"email" : "email", "password" : "oldpass"}) is not None
And which the getUserPassword itself is returning a string

not getting expected result from sql query select python

I am trying to select from a specific row and then column in SQL.
I want to find a specific user_name row and then select the access_id from the row.
Here is all of my code.
import sys, ConfigParser, numpy
import MySQLdb as mdb
from plaid.utils import json
class SQLConnection:
"""Used to connect to a SQL database and send queries to it"""
config_file = 'db.cfg'
section_name = 'Database Details'
_db_name = ''
_hostname = ''
_ip_address = ''
_username = ''
_password = ''
def __init__(self):
config = ConfigParser.RawConfigParser()
config.read(self.config_file)
print "making"
try:
_db_name = config.get(self.section_name, 'db_name')
_hostname = config.get(self.section_name, 'hostname')
_ip_address = config.get(self.section_name, 'ip_address')
_user = config.get(self.section_name, 'user')
_password = config.get(self.section_name, 'password')
except ConfigParser.NoOptionError as e:
print ('one of the options in the config file has no value\n{0}: ' +
'{1}').format(e.errno, e.strerror)
sys.exit()
self.con = mdb.connect(_hostname, _user, _password, _db_name)
self.con.autocommit(False)
self.con.ping(True)
self.cur = self.con.cursor(mdb.cursors.DictCursor)
def query(self, sql_query, values=None):
"""
take in 1 or more query strings and perform a transaction
#param sql_query: either a single string or an array of strings
representing individual queries
#param values: either a single json object or an array of json objects
representing quoted values to insert into the relative query
(values and sql_query indexes must line up)
"""
# TODO check sql_query and values to see if they are lists
# if sql_query is a string
if isinstance(sql_query, basestring):
self.cur.execute(sql_query, values)
self.con.commit()
# otherwise sql_query should be a list of strings
else:
# execute each query with relative values
for query, sub_values in zip(sql_query, values):
self.cur.execute(query, sub_values)
# commit all these queries
self.con.commit
return self.cur.fetchall
def get_plaid_token(self,username):
result= self.query("SELECT access_id FROM `users` WHERE `user_name` LIKE %s",[username])
print type (result)
return result
print SQLConnection().get_plaid_token("test")
I would like the get the transaction ID but for some reason "result" returns
> <bound method DictCursor.fetchall of <MySQLdb.cursors.DictCursor
> object at 0x000000000396F278>>
result is also of type "instancemethod"
try changing this line:
return self.cur.fetchall
to
return self.cur.fetchall()
Without the parentheses after the method name, you are returning a reference to that method itself, not running the method.

Removing quotes from mysql query in Python

I know that this question has been asked in the past, but thorough searching hasn't seemed to fix my issue. I'm probably just missing something simple, as I'm new to the Python-mysql connector supplied by mysql.
I have a Python script which accesses a mysql database, but I'm having issues with removing quotes from my query. Here is my code:
import mysql.connector
try:
db = mysql.connector.connect(user='root', password='somePassword', host='127.0.0.1', database='dbName')
cursor = db.cursor()
query = "select * from tags where %s = %s"
a = 'tag_id'
b = '0'
cursor.execute(query, (a, b))
print cursor
data = cursor.fetchall()
print data
except mysql.connector.Error as err:
print "Exception tripped..."
print "--------------------------------------"
print err
cursor.close()
db.close()
My database is set up properly (as I'll prove shortly).
My output for this program is:
MySQLCursor: select * from tags where 'tag_id' = '0'
[]
Yet when I change my query to not use variables, for example:
cursor.execute("select * from tags where tag_id = 0")
Then my output becomes:
MySQLCursor: select * from tags where tag_id = 0
[(0, u'192.168.1.110')]
To me, this means that the only difference between my Cursor queries are the quotes.
How do I remove them from the query?
Thanks in advance.
I personally believe this code is correct and safe, but you should be extremely skeptical of using code like this without carefully reviewing it yourself or (better yet) with the help of a security expert. I am not qualified to be such an expert.
Two important things I changed:
I changed b = '0' to b = 0 so it ends up as a number rather than a quoted string. (This part was an easy fix.)
I skipped the built-in parameterization for the column name and replaced it with my own slight modification to the escaping/quoting built in to mysql-connector. This is the scary part that should give you pause.
Full code below, but again, be careful with this if the column name is user input!
import mysql.connector
def escape_column_name(name):
# This is meant to mostly do the same thing as the _process_params method
# of mysql.connector.MySQLCursor, but instead of the final quoting step,
# we escape any previously existing backticks and quote with backticks.
converter = mysql.connector.conversion.MySQLConverter()
return "`" + converter.escape(converter.to_mysql(name)).replace('`', '``') + "`"
try:
db = mysql.connector.connect(user='root', password='somePassword', host='127.0.0.1', database='dbName')
cursor = db.cursor()
a = 'tag_id'
b = 0
cursor.execute(
'select * from tags where {} = %s'.format(escape_column_name(a)),
(b,)
)
print cursor
data = cursor.fetchall()
print data
except mysql.connector.Error as err:
print "Exception tripped..."
print "--------------------------------------"
print err
cursor.close()
db.close()
I encountered a similar problem using pymysql and have shown my working code here, hope this will help.
What I did is overwrite the escape method in class 'pymysql.connections.Connection', which obviously adds "'" arround your string.
better have shown my code:
from pymysql.connections import Connection, converters
class MyConnect(Connection):
def escape(self, obj, mapping=None):
"""Escape whatever value you pass to it.
Non-standard, for internal use; do not use this in your applications.
"""
if isinstance(obj, str):
return self.escape_string(obj) # by default, it is :return "'" + self.escape_string(obj) + "'"
if isinstance(obj, (bytes, bytearray)):
ret = self._quote_bytes(obj)
if self._binary_prefix:
ret = "_binary" + ret
return ret
return converters.escape_item(obj, self.charset, mapping=mapping)
config = {'host':'', 'user':'', ...}
conn = MyConnect(**config)
cur = conn.cursor()

Categories

Resources