"AttributeError: __exit__" when importing data in SQL database - python

I am currently following alongside a book (cpp for quantitative finance) and I am trying to import the symbols for S&P500 from wiki into a sql database I've created. However, I am getting the AttributeError: exit with regards to my "with con" statement (see below). I have read posts from similar errors but I cannot seem to fix mine. I am extremely new to python so perhaps there is some fundamental misunderstanding on my part. I have included the relevant code below, any advice would be hugely appreciated.
"""
Insert the S&P500 symbols into the MySQL database.
"""
# Connect to the MySQL instance
db_host = 'localhost'
db_user = 'sec_user'
db_pass = 'database_password'
db_name = 'database_name'
con = mdb.connect(
host=db_host, user=db_user, passwd=db_pass, db=db_name
)
# Create the insert strings
column_str = """ticker, instrument, name, sector,
currency, created_date, last_updated_date
"""
insert_str = ("%s, " * 7)[:-2]
final_str = "INSERT INTO symbol (%s) VALUES (%s)" % \
(column_str, insert_str)
# Using the MySQL connection, carry out
# an INSERT INTO for every symbol
with con:
cur = con.cursor()
cur.executemany(final_str, symbols)
if __name__ == "__main__":
symbols = obtain_parse_wiki_snp500()
insert_snp500_symbols(symbols)
print("%s symbols were successfully added." % len(symbols))

The error is telling you that the object returned by mdb.connect is not a context manager, that is it cannot be used in a with statement. You'll need to close the connection manually once you've finished with it (con.close()) or use a package that provides a connection that is a context manager.
A quick study of commonly used connectors suggests you want to use pymysql
>>> import MySQLdb
>>> import mysql.connector
>>> import pymysql
>>> params = {'host': 'localhost', 'user': 'root', 'password': '', 'database': 'test'}
>>> for pkg in (MySQLdb, mysql.connector, pymysql):
... conn = pkg.connect(**params)
... try:
... with conn:
... pass
... except AttributeError as ex:
... print(pkg.__name__, 'failed with', ex)
...
MySQLdb failed with __enter__
mysql.connector failed with __enter__
If you have to use a connection that is not a context manager, you can emulate it in a try/except/finally suite:
import MySQLdb
conn = MySQLdb.connect(host='localhost', user='root', password='', database='test')
try:
cursor = conn.cursor()
cursor.execute('SELECT * FROM my_table;')
for row in cursor.fetchall():
print(row)
cursor.close()
conn.commit()
except:
# log the error here
conn.rollback()
finally:
conn.close()
Or you can make your own context manager using the tools provided in contextlib:
import contextlib
import MySQLdb
#contextlib.contextmanager
def managed_connection(conn):
try:
yield
conn.commit()
except:
# log the error here
conn.rollback()
finally:
conn.close()
conn = MySQLdb.connect(host='localhost', user='root', password='', database='test')
with managed_connection(conn) as mc:
cursor = mc.cursor()
cursor.execute('SELECT * FROM my_table;')
for row in cursor.fetchall():
print(row)
cursor.close()
(You can make a cursor context manager too, or have the context manager yield a cursor rather than the connection).

Related

Python update query in mariadb

I am trying to update my mariadb table via python code .While compile the query nothing happen in my database. please check below code and let me know where i made mistake in update function
import mariadb
connection= mariadb.connect(user="user1", database="db1", host="ippp" ,password="pass")
cursor= connection.cursor()
cursor.execute("UPDATE product_options_combinations SET quantity=5944 WHERE item_code ='31628'")
cursor.close()
connection.close()
Hello here I have a clean code example for you. How to update it.
import pymysql
# Create a connection object
# IP address of the MySQL database server
Host = "localhost"
# User name of the database server
User = "user"
# Password for the database user
Password = ""
database = "GFG"
conn = pymysql.connect(host=Host, user=User, password=Password, database)
# Create a cursor object
cur = conn.cursor()
query = f"UPDATE PRODUCT SET price = 1400 WHERE PRODUCT_TYPE = 'broadband'"
cur.execute(query)
#To commit the changes
conn.commit()
conn.close()
You just need to add connection.commit() to your code, but I recommend you use a parametrized SQL preferably with a list of tuples,more of which might be added if needed, along with cursor.executemany() as being more performant for DML statements such as
import mariadb
connection= mariadb.connect(user="user1",
password="pass",
host="ippp",
port=3306,
database="db1")
cursor= connection.cursor()
dml="""
UPDATE product_options_combinations
SET quantity=%s
WHERE item_code =%s
"""
val=[
(5944,'31628')
]
cursor.executemany(dml,val)
connection.commit()
cursor.close()
connection.close()
Are you sure that the connection is working properly?
Have you tried to implement a try and catch routine to print mariadb errors?
Something like this:
# Connect to MariaDB Platform
import mariadb
try:
conn = mariadb.connect(
user="user",
password="password",
host="xx.xx.xx.xx",
port=3306,
database="db_name"
)
except mariadb.Error as e:
print(f"Error connecting to MariaDB Platform: {e}")
sys.exit(1)

My SQL with Python: Select the row with the highest value and change the value there

I have already searched for several solutions here and tried to get a working code. Everything works except for the where query.
In the where query I search for the highest value (numeric). However, this does not really work...
Here is my code and the structure of the MySQL database.
Thanks!
import pymysql
conn = pymysql.connect(host='localhost', unix_socket='', user='root', passwd='pw', db='database')
cur = conn.cursor()
cur.execute("SELECT * FROM dose")
for r in cur:
curr = conn.cursor()
sql = """UPDATE dose
SET status = "printed"
WHERE id = SELECT GREATEST (status) FROM dose (status);"""
# print(sql)
try:
# Execute the SQL command
curr.execute(sql)
# Commit your changes in the database
conn.commit()
except:
# Rollback in case there is any error
conn.rollback()
curr.close()
cur.close()
conn.close()
My SQL Database
You have a lot of things wrong in your code.
You don´t use the results of your first select query, and the only thing that you do is iterate over the results to execute an UPDATE
Your update query is wrong
You should change it to:
import pymysql
conn = pymysql.connect(host='localhost', unix_socket='', user='root', passwd='pw', db='database')
curr = conn.cursor()
sql = """UPDATE dose
SET status = 'printed'
WHERE id = (SELECT max(status) FROM dose) """
try:
# Execute the SQL command
curr.execute(sql)
# Commit your changes in the database
conn.commit()
except:
# Rollback in case there is any error
conn.rollback()
curr.close()
conn.close()

Python don't register in MySQL server

there’s something wrong in my python script: when I try to put some data in my database and print it, it looks like it’s working, but when I rerun the code, or if I check the phpmyadmin, there’s no data saved in the db. Does anyone have some idea on how to solve this problem?
import mysql.connector
from mysql.connector import errorcode
def connect():
""" Connect to MySQL database """
try:
conn = mysql.connector.connect(host='localhost',
database='Temperature',
user='Temperature',
password='mypass')
if conn.is_connected():
print('Connected to MySQL database')
cur = conn.cursor()
query = "INSERT INTO Temp(temp, humi) " \
"VALUES(315, 55)"
try:
cur.execute(query)
except MySQLdb.ProgrammingError as e:
print(e)
query = "SELECT * FROM Temp"
try:
cur.execute(query)
for reading in cur.fetchall():
print (str(reading[0])+" "+str(reading[1]))
except MySQLdb.ProgrammingError as e:
print(e)
except Error as e:
print(e)
finally:
conn.close()
if __name__ == '__main__':
connect()
You will need to add conn.commit() before conn.close(). That should solve the problem.

Sqlite insert query not working with python?

I have been trying to insert data into the database using the following code in python:
import sqlite3 as db
conn = db.connect('insertlinks.db')
cursor = conn.cursor()
db.autocommit(True)
a="asd"
b="adasd"
cursor.execute("Insert into links (link,id) values (?,?)",(a,b))
conn.close()
The code runs without any errors. But no updation to the database takes place. I tried adding the conn.commit() but it gives an error saying module not found. Please help?
You do have to commit after inserting:
cursor.execute("Insert into links (link,id) values (?,?)",(a,b))
conn.commit()
or use the connection as a context manager:
with conn:
cursor.execute("Insert into links (link,id) values (?,?)", (a, b))
or set autocommit correctly by setting the isolation_level keyword parameter to the connect() method to None:
conn = db.connect('insertlinks.db', isolation_level=None)
See Controlling Transactions.
It can be a bit late but set the autocommit = true save my time! especially if you have a script to run some bulk action as update/insert/delete...
Reference: https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.isolation_level
it is the way I usually have in my scripts:
def get_connection():
conn = sqlite3.connect('../db.sqlite3', isolation_level=None)
cursor = conn.cursor()
return conn, cursor
def get_jobs():
conn, cursor = get_connection()
if conn is None:
raise DatabaseError("Could not get connection")
I hope it helps you!

About MySQLdb conn.autocommit(True)

I have installed python 2.7 64bit,MySQL-python-1.2.3.win-amd64-py2.7.exe.
I use the following code to insert data :
class postcon:
def POST(self):
conn=MySQLdb.connect(host="localhost",user="root",passwd="mysql",db="dang",charset="utf8")
cursor = conn.cursor()
n = cursor.execute("insert into d_message (mid,title,content,image) values(2,'xx','ccc','fff')")
cursor.close()
conn.close()
if n:
raise web.seeother('/')
This results in printing n as 1, but in mysql client data aren't visible.
google says I must add conn.autocommit(True).
but I don't know why MySQLdb turns it off;
by default MySQLdb autocommit is false,
You can set autocommit to True in your MySQLdb connection like this,
conn=MySQLdb.connect(host="localhost",user="root",passwd="mysql",db="dang",charset="utf8")
conn.get_autocommit() #will return **False**
conn.autocommit(True)
conn.get_autocommit() #Should return **True** now
cursor = conn.cursor()
I don't know if there's a specific reason to use autocommit with GAE (assuming you are using it). Otherwise, you can just manually commit.
class postcon:
def POST(self):
conn=MySQLdb.connect(host="localhost",user="root",passwd="mysql",db="dang",charset="utf8")
cursor = conn.cursor()
n = cursor.execute("insert into d_message (mid,title,content,image) values(2,'xx','ccc','fff')")
conn.commit() # This right here
cursor.close()
conn.close()
if n:
raise web.seeother('/')
Note that you probably should check if the insert happened successfully, and if not, rollback the commit.
Connector/Python Connection Arguments
Turning on autocommit can be done directly when you connect to a database:
import mysql.connector as db
conn = db.connect(host="localhost", user="root", passwd="pass", db="dbname", autocommit=True)
or
import mysql.connector
db = mysql.connector.connect(option_files='my.conf', autocommit=True)
Or call conn.commit() before calling close.

Categories

Resources