I currently have many scripts that connect to the same MSSQL database. I make the connection in each of the scripts, but for ease of use I want to put the connection in a module and call that module from my script. The code in my module connect_to_db.pyc looks like this:
import pyodbc
def sql_connect():
server="some_server.net"
port="1433"
user = "my_username#my_domain"
server="my_server"
database="my_database"
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my_server,1433',
user=user,
password=password,
database=database)
c=conn.cursor()
Then, in my script I try to call this module and run a query:
from connect_to_db import sql_connect
sql_connect()
c.execute("SELECT * FROM table")
I get the error that the name c is not defined. I tried to define it as a global too, but it don't help. It must have something to do with my lack of understanding modules, but I can't figure out what.
You can return cursor in your sql_connect function
import pyodbc
def sql_connect():
server="some_server.net"
port="1433"
user = "my_username#my_domain"
server="my_server"
database="my_database"
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my_server,1433',
user=user,
password=password,
database=database)
return conn.cursor()
And then you can use it as
from connect_to_db import sql_connect
c = sql_connect()
c.execute("SELECT * FROM table")
You are indeed missing a bit there:
in your function sql_connect, you assign to a local variable named c.
That variable is not existant outside your function.
If you want a connection variable to exist on module level, maybe try the following attempt:
In your "connect_to_db.py":
import pyodbc
def sql_connect():
server="some_server.net"
port="1433"
user = "my_username#my_domain"
server="my_server"
database="my_database"
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my_server,1433',
user=user,
password=password,
database=database)
return conn.cursor()
cursor = sql_connect()
This creates a varibale "cursor" on the level of the module.
In another module, simply perform
from connect_to_db import cursor
to import the module's "cursor" member.
This should do the trick.
Hint: Please be advised that this approach may not be very elegant, in terms of software-engineering.
Edit:
Maybe, you may want to dive deeper into object-oriented programming?
class MSSQLConnector(object):
def __init__(self, server, port, database, user, password):
self.server = server
self.port = port
self.conn = pyodbc.connect('DRIVER={SQL Server};SERVER='{0},
{1}.format((self.server, self.port)), user, password, database)
def open_cursor(self):
return self.conn.cursor()
Which would be used in this fashion:
connector = MSSQLConnector("my_server", "1433", "my_database", "username", "secret-password")
cursor = connector.open_cursor()
Related
I'm trying to create a function for oracle connection which will take the parameters as mentioned in below code, but seems some issue...
could anyone please help in understanding how it can be corrected and what i'm missing here?
import cx_Oracle
def sqlconnect(user,passwd,SID, query):
connStr = cx_Oracle.connect('user/passwd#SID')
cursor = connStr.cursor()
cursor.execute(query)
return cursor.fetchall()
if __name__ == '__main__':
sqlconnect('user','password','XEE','select * from dual')
Thanks in advance!
The string user/passwd#SID is not a valid connect string. Unless XEE is a tnsnames.ora entry you need to reference the host and service name in your connect string. You probably want something like this, instead:
def sqlconnect(user, passwd, dsn, query):
conn = cx_Oracle.connect(user=user, password=passwd, dsn=dsn)
cursor = conn.cursor()
cursor.execute(query)
return cursor.fetchall()
if __name__ == '__main__':
host = "my_host_name"
service_name = "XEE"
conn_string = f"{host}/{service_name}"
sqlconnect("user", "password", conn_string, "select * from dual")
You can refer below link which helps you to understand how Python connects to Oracle db and you are missing TNS entry or full service JDBC URL and below are some samples:
https://www.oracle.com/database/technologies/appdev/python/quickstartpythononprem.html
https://oracle.github.io/python-cx_Oracle/samples/tutorial/Python-and-Oracle-Database-Scripting-for-the-Future.html
I think there's also another way by using f-strings:
import cx_Oracle
def sqlconnect(user,passwd,dsn, query):
connStr = cx_Oracle.connect(f'{user}/{passwd}#{dsn}')
cursor = connStr.cursor()
cursor.execute(f'{query}')
return cursor.fetchall()
if __name__ == '__main__':
sqlconnect('user','password','localhost/SID','select * from dual')
I want to fetch data from PostgreSQL database through python script. In where condition I have to use a value from local variable called "lastrun" last run is nothing but I have stored the last time when the program gets executed in a file. After read that file I stored that value in a variable called "lastrun" and I wanna use it in the query.
lastrun="06/11/2020 08:20:50.949881"
def doQuery( conn ):
cur = conn.cursor()
cur.execute("SELECT accountno,req, type, site,ref FROM accounts WHERE created > lastrun")
records=cur.fetchall()
print("Using PyGreSQL…")
import pgdb
myConnection = pgdb.connect( host=hostname, user=username, password=password, database=database )
doQuery( myConnection )
myConnection.close()
I tried but nothing works for me. Please help me out.
Thanks in advance.
you can use python string formatting to achive this
lastrun="06/11/2020 08:20:50.949881"
def doQuery( conn ):
cur = conn.cursor()
cur.execute("SELECT accountno,req, type, site,ref FROM accounts WHERE created > '%s'"%lastrun)
records=cur.fetchall()
print("Using PyGreSQL…")
import pgdb
myConnection = pgdb.connect( host=hostname, user=username, password=password, database=database )
doQuery( myConnection )
myConnection.close()
for more info visit here.
This is probably a stupid question but I cannot find the information in the documentation for pymysql. What is the pymysql default cursorclass? When I do not specify a cursor class on connection to the database my queries return a list for each row in the response.
When I specify pymysql.cursors.DictCursor I get a dictionary response. I would like to be able to change between them for different connections within a script.
I've written a little function with a context manager to yield the cursor but it requires me to specify the name of the cursorclass each time. I know I can get around this, but knowing the name of the default cursorclass would be nice.
from contextlib import contextmanager
import pymysql
#contextmanager
def openDb(host=DB_HOST, database=DB_DATABASE,
user=DB_USER, cursor=DB_CURSOR):
"""
Simple context manager for opening a db connection
"""
with pymysql.connect(host=host, database=database, user=user,
cursorclass=cursor) as cur:
yield cur
I could probably write this as:
#contextmanager
def openDb(host=DB_HOST, database=DB_DATABASE,
user=DB_USER, cursor=None):
"""
Simple context manager for opening a db connection
"""
if cursor:
with pymysql.connect(host=host, database=database, user=user,
cursorclass=cursor) as cur:
yield cur
else:
with pymysql.connect(host=host, database=database, user=user) as cur:
yield cur
and let it default to whatever the default cursorclass is, but I would prefer to be explicit.
Of course as soon as I post this I find the answer in via:
>>> import pymysql
>>> help(pymysql.cursors)
Help on module pymysql.cursors in pymysql:
NAME
pymysql.cursors - # -*- coding: utf-8 -*-
CLASSES
builtins.object
Cursor
SSCursor
DictCursorMixin
DictCursor(DictCursorMixin, Cursor)
SSDictCursor(DictCursorMixin, SSCursor)
pymysql.cursors.Cursor is the answer. Documentation...
I have a simple web.py-based app that uses MySQLdb. I have a class that handles database operations like so:
class db():
def __init__(self):
db = MySQLdb.connect(host='mysql.server', user='user', passwd='pass', db='app')
self.cur = db.cursor()
def get_data(self):
sql = "SELECT * FROM foobar"
self.cur.execute(sql)
rs = self.cur
r.fetchall()
return rs
I instantiate the class like so DB = db(). Then, in another class, I will refer to it.
class bleh()
def blarg():
DB.get_data()
With something like this, where would I close the cursor and connection? Or am I approaching this completely wrong?
db.close() for connection and cur.close() for cursor.
http://mysql-python.sourceforge.net/MySQLdb.html
EDIT:
But if it give it a bit thought - you won't need to close cursor. Python closes the cursor once the variable is destroyed, so when the instance of your class does not exist anymore -- cursor will be closed.
First of all use different names for class-name and variable as you have used same name ('db') for class-name and connection as well.
Next, you need to define conn (in your question db line no 3) as self.conn.
import MySQLdb
class db():
def __init__(self):
self.conn = MySQLdb.connect(host='mysql.server', user='user', passwd='pass', db='app')
self.cur = self.conn.cursor()
def get_data(self):
sql = "SELECT * FROM test"
self.cur.execute(sql)
rs = self.cur
rs.fetchall()
return rs
class bleh()
def blarg():
data = DB.get_data()
DB.cur.close()
DB.conn.close()
Note: If you have multiple functions in class bleh to get data from database make sure that you close cursor and connection in function, which is to called in last. Or you may have a seperate function, which closes cursor and connection.
I am used to (spoiled by?) python's SQLite interface to deal with SQL databases. One nice feature in python's SQLite's API the "context manager," i.e., python's with statement. I usually execute queries in the following way:
import as sqlite
with sqlite.connect(db_filename) as conn:
query = "INSERT OR IGNORE INTO shapes VALUES (?,?);"
results = conn.execute(query, ("ID1","triangle"))
With the code above, if my query modifies the database and I forget to run conn.commit(),the context manager runs it for me automatically upon exiting the with statement. It also handles exceptions nicely: if an exception occurs before I commit anything, then the database is rolled back.
I am now using the MySQLdb interface, which doesn't seem to support a similar context manager out of the box. How do I create my own? There is a related question here, but it doesn't offer a complete solution.
Previously, MySQLdb connections were context managers.
As of this commit on 2018-12-04, however, MySQLdb connections are no longer context managers,
and users must explicitly call conn.commit() or conn.rollback(), or write their own context manager, such as the one below.
You could use something like this:
import config
import MySQLdb
import MySQLdb.cursors as mc
import _mysql_exceptions
import contextlib
DictCursor = mc.DictCursor
SSCursor = mc.SSCursor
SSDictCursor = mc.SSDictCursor
Cursor = mc.Cursor
#contextlib.contextmanager
def connection(cursorclass=Cursor,
host=config.HOST, user=config.USER,
passwd=config.PASS, dbname=config.MYDB,
driver=MySQLdb):
connection = driver.connect(
host=host, user=user, passwd=passwd, db=dbname,
cursorclass=cursorclass)
try:
yield connection
except Exception:
connection.rollback()
raise
else:
connection.commit()
finally:
connection.close()
#contextlib.contextmanager
def cursor(cursorclass=Cursor, host=config.HOST, user=config.USER,
passwd=config.PASS, dbname=config.MYDB):
with connection(cursorclass, host, user, passwd, dbname) as conn:
cursor = conn.cursor()
try:
yield cursor
finally:
cursor.close()
with cursor(SSDictCursor) as cur:
print(cur)
connection = cur.connection
print(connection)
sql = 'select * from table'
cur.execute(sql)
for row in cur:
print(row)
To use it you would place config.py in your PYTHONPATH and define the HOST, USER, PASS, MYDB variables there.
Think things have changed since this question was originally asked. Somewhat confusingly (from my point of view at least), for recent versions of MySQLdb, if you use a connection in a context you get a cursor (as per the oursql example), not something that closes automatically (as you would if you opened a file for instance).
Here's what I do:
from contextlib import closing
with closing(getConnection()) as conn: #ensure that the connection is closed
with conn as cursor: #cursor will now auto-commit
cursor.execute('SELECT * FROM tablename')