Python 2.7 connection string to PostgreSQL (OOP method) - python

I'm new to python and I'm trying to make this work. I'm using Python 2.7 and PostgreSQL 9.3:
#! F:\Python2.7.6\python
import psycopg2
class Database:
host = "192.168.56.101"
user = "testuser"
passwd = "passwd"
db = "test"
def __init__(self):
self.connection = psycopg2.connect( host = self.host,
user = self.user,
password = self.passwd,
dbname = self.db )
self.cursor = self.connection.cursor
def query(self, q):
cursor = self.cursor
cursor.execute(q)
return cursor.fetchall()
def __del__(self):
self.connection.close()
if __name__ == "__main__":
db = Database()
q = "DELETE FROM testschema.test"
db.query(q)
However I am getting an error "AttributeError: 'builtin_function_or_method' object has no attribute 'execute'". I figure I should put something like self.execute = something in the Database class, but I can't figure it out what exactly I need to put there. Any suggestions?

You are missing the parenthesis at the end
self.cursor = self.connection.cursor()
or
cursor = self.cursor()
But not both

Related

Can I get dictionary from pymysql?

I have a following question. I would like to get content of a table in dictionary format. My code:
from configparser import ConfigParser
import pymysql as mysql
class Database:
def __init__(self):
config = ConfigParser()
config.read("config.ini")
user = config["db"]["user"]
passwd = config["db"]["password"]
host = config["db"]["host"]
db = config["db"]["database"]
self.connection = mysql.connect(
user=user,
passwd=passwd,
host=host,
db=db,
)
self.cursor = self.connection.cursor()
def init_dict(self):
query = """
SELECT a, b
FROM mytable
"""
self.cursor.execute(query)
data = self.cursor.fetchall()
return dict(data)
Is there a more pythonic way how to get data in the method init_dict as a dictionary? I found, that it should be possible to return a dict directly from the cursor, but I don`t know how. Thanks a lot.

AttributeError: 'NoneType' object has no attribute 'fetchall'

I tried to return the result of an SQL query.
This works perfectly with pyodbc but not with mysql-connector.
Error Output
File "/mySQLDB.py", line 17, in execute_and_fetch
result = conn.cursor().execute(query, params).fetchall()
AttributeError: 'NoneType' object has no attribute 'fetchall'
Code
import mysql.connector
class MYSQLDB:
def __init__(self):
self.host = 'xx'
self.database = 'xx$xx'
self.user = 'xx'
self.password = 'xx'
def execute(self, query, *params):
mysql.connector.connect(host=self.host, database=self.database,
user=self.user, password=self.password).cursor().execute(query, params).commit()
def execute_and_fetch(self, query, *params):
conn = mysql.connector.connect(host=self.host, database=self.database,
user=self.user, password=self.password)
result = conn.cursor().execute(query, params).fetchall()
conn.commit()
return result
PEP 249, the DBAPI spec, says that the return value of execute is undefined. Quite a few DBAPI implementations return None, meaning that you cannot (portably) chain execute().fetchall() as you are trying to do.
Try this code.
If you are still having problems check that the connection to the database is successful.
import mysql.connector
class MYSQLDB:
def __init__(self):
self.host = 'xx'
self.database = 'xx$xx'
self.user = 'xx'
self.password = 'xx'
def execute(self, query, *params):
mysql.connector.connect(host=self.host, database=self.database,
user=self.user, password=self.password).cursor().execute(query, params).commit()
def execute_and_fetch(self, query, *params):
conn = mysql.connector.connect(host=self.host, database=self.database,
user=self.user, password=self.password)
with conn.cursor() as cursor:
cursor.execute(query, params=None)
... result = cursor.fetchall()
conn.commit()
return result

How to modularize a code containing 'with' in Python

I have this code that I am using to get information from a mysql database
def query_result_connect(_query):
with SSHTunnelForwarder((ssh_host, ssh_port),
ssh_password=ssh_password,
ssh_username=ssh_user,
remote_bind_address=('127.0.0.1', 3306)) as server:
connection = mdb.connect(user=sql_username,
passwd=sql_password,
db=sql_main_database,
host='127.0.0.1',
port=server.local_bind_port)
cursor = connection.cursor()
cursor.execute(_query)
connection.commit()
try:
y = pd.read_sql(_query, connection)
return y
except TypeError as e:
x = cursor.fetchall()
return x
I would like to create a function that includes the following part.
with SSHTunnelForwarder((ssh_host, ssh_port),
ssh_password=ssh_password,
ssh_username=ssh_user,
remote_bind_address=('127.0.0.1', 3306)) as server:
connection = mdb.connect(user=sql_username,
passwd=sql_password,
db=sql_main_database,
host='127.0.0.1',
port=server.local_bind_port)
and execute it in the query_result_connect() function. The problem is that I don't know how to include more code within the 'with' statement. The code should look something like this:
# Maybe introduce some arguments
def db_connection():
with SSHTunnelForwarder((ssh_host, ssh_port),
ssh_password=ssh_password,
ssh_username=ssh_user,
remote_bind_address=('127.0.0.1', 3306)) as server:
connection = mdb.connect(user=sql_username,
passwd=sql_password,
db=sql_main_database,
host='127.0.0.1',
port=server.local_bind_port)
# Maybe return something
def query_result_connect(_query):
# call the db_connection() function somehow.
# Write the following code in a way that is within the 'with' statement of the db_connection() function.
cursor = connection.cursor()
cursor.execute(_query)
connection.commit()
try:
y = pd.read_sql(_query, connection)
return y
except TypeError as e:
x = cursor.fetchall()
return x
Thank you
What's about to make "do_connection" to be a context manager itself?
#contextmanager
def do_connection():
# prepare connection
# yield connection
# close connection (__exit__). Perhaps you even want to call "commit" here.
Then, you will use it like this:
with do_connection() as connection:
cursor = connection.cursor()
...
It is a common approach to use context managers for creating DB connections.
You could make you own Connection class, that works like a conext manager.
__enter__ sets up ssh tunnel and db connection.
__exit__, tries to close the cursor, db connection and the ssh tunnel.
from sshtunnel import SSHTunnelForwarder
import psycopg2, traceback
class MyDatabaseConnection:
def __init__(self):
self.ssh_host = '...'
self.ssh_port = 22
self.ssh_user = '...'
self.ssh_password = '...'
self.local_db_port = 59059
def _connect_db(self, dsn):
try:
self.con = psycopg2.connect(dsn)
self.cur = self.con.cursor()
except:
traceback.print_exc()
def _create_tunnel(self):
try:
self.tunnel = SSHTunnelForwarder(
(self.ssh_host, self.ssh_port),
ssh_password=self.ssh_password,
ssh_username=self.ssh_user,
remote_bind_address=('localhost', 5959),
local_bind_address=('localhost', self.local_db_port)
)
self.tunnel.start()
if self.tunnel.local_bind_port == self.local_db_port:
return True
except:
traceback.print_exc()
def __enter__(self):
if self._create_tunnel():
self._connect_db(
"dbname=mf port=%s host='localhost' user=mf_usr" %
self.local_db_port
)
return self
def __exit__(self, *args):
for c in ('cur', 'con', 'tunnel'):
try:
obj = getattr(self, c)
obj.close()
obj = None
del obj
except:
pass
with MyDatabaseConnection() as db:
print(db)
db.cur.execute('Select count(*) from platforms')
print(db.cur.fetchone())
Out:
<__main__.MyDatabaseConnection object at 0x1017cb6d0>
(8,)
Note:
I am connecting to Postgres, but that should work using mysql as well. Probably you need to adjust to match your own needs.

Use multiple functions in MySQLdb (python)

this code below runs just fine, but i want to separate this code into function (this is my first time using MySQLdb) ,
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","user_name","pass","db_name" )
cursor = db.cursor()
sql = "SELECT activity_log.datetime FROM activity_log"
cursor.execute(sql)
date_data = cursor.fetchall()
for content in date_data:
print content
# disconnect from server
db.close()
Question: how could I create one database connection and use it to multiple functions, this is what i've wrote so far (doesn't work):
import MySQLdb
class DB():
def __init__(self):
db = MySQLdb.connect("locahost", "user_name", "pass", "db_name")
self.cur = db.cursor()
def time_statistic(self):
sql = "SELECT activity_log.datetime FROM activity_log"
self.cur.execute(sql)
self.date_data = self.cursor.fetchone()
for content in self.date_data:
print content
def test1(self):
pass
if __name__ == '__main__':
db = DB.connect("db_name" )
db.time_statistic(self)
db.test1(self)
db.close()
You need to pass the arguments to init to make sure that the class connects to the right DB.
import MySQLdb
class DB():
def __init__(self, server, user, password, db_name):
db = MySQLdb.connect(server, user, password, db_name)
self.cur = db.cursor()
def time_statistic(self):
sql = "SELECT activity_log.datetime FROM activity_log"
self.cur.execute(sql)
self.date_data = self.cursor.fetchone()
for content in self.date_data:
print content
def test1(self):
pass
if __name__ == '__main__':
db = DB(<server>, <user>, <password>, <db_name>)
db.time_statistic()
db.test1()
Replace the arguments in <> with actual values you need to connect to the db. You may also want to add some error handling in the above code.

Unable to execute Postgres queries in Python

I'm trying to create a Postgres table using psycopg2 in Python as follows:
import psycopg2
class DbOperations (object):
def __init__(self):
self.dummy = None
self.conn = None
self.cur = None
self.query = None
self.db_name = "alarm_log"
self.table_name = "alarms"
self.user = "cayman"
self.password = "admin"
self.host = "127.0.0.1"
def db_connect(self):
self.conn = psycopg2.connect(dbname=self.db_name, user=self.user, password=self.password, host=self.host)
self.cur = self.conn.cursor()
def db_disconnect(self):
self.conn.close()
def db_create_table(self):
self.query ="""
CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
"""
print (self.query)
self.cur.execute(self.query)
Then I construct the object as follows:
db_app = DbOperations()
db_app.db_connect()
db_app.db_create_table()
I am able to manually connect to the database and create the table. However, I'm not able to do so using Python.
There are no exceptions or error messages. When I try to list the tables in the database manually, I don't find my newly created table.
Any suggestions what could be wrong ?
Seems, you are missing the commit at the end of db_create_table method:
self.conn.commit()
Iron Fist's answer is absolutely correct, but if you don't want to have commits all over your code, you can also set it on the connection like this:
def db_connect(self):
self.conn = psycopg2.connect(dbname=self.db_name, user=self.user, password=self.password, host=self.host)
self.conn.autocommit = True
self.cur = self.conn.cursor()

Categories