Reputation: 1342
I wish to set a custom runtime parameter in postgresql every time I get the cursor for a connection.
I added the variables in postgresql.conf like so:
currentuser.name = 'not set'
currentuser.reasonid = -1
Now, my solution so far was to create a custom cursor class and then pass it as argument to the cursor()
function:
import psycopg2
import psycopg2.extensions
class mycursor(psycopg2.extensions.cursor):
def __init__(self, username, *args, **kwargs):
username = kwargs['username']
del kwargs['username']
super(mycursor, self).__init__(*args, **kwargs)
self.execute("select set_config('currentuser.name', %s, false)", [username])
connection = psycopg2.connect(database="my_database",
user="my_user",
password="my_password",
host='127.0.0.1')
cursor = connection.cursor(cursor_factory=mycursor, username='michael')
cursor.execute("select current_setting('currentuser.name')")
user = cursor.fetchall()[0][0]
print user
cursor.close()
This produces the TypeError
:
Traceback (most recent call last):
File "customdb.py", line 22, in <module>
cursor = connection.cursor(cursor_factory=mycursor, username='michael')
TypeError: 'username' is an invalid keyword argument for this function
Upvotes: 2
Views: 737
Reputation: 149195
The signature for connection.cursor
does not allow any additional parameter. That explains your error.
It would be simpler to sub-class the connection itself, because that way you could easily override the method cursor
. Here is my implementation, that delegates all processing to an embedded connection
object, except for the cursor creation :
import psycopg2
import psycopg2.extensions
class myconnection(psycopg2.extensions.connection):
def __init__(self, database, user, password, host = 'localhost',
port=5432, **kwargs):
self.__dict__['conn'] = psycopg2.connect(dsn = None, database = database, user=user,
password=password, host=host, port=port, **kwargs)
self.__dict__['username'] = user
def cursor(self, username=None, **kwargs):
curs = self.conn.cursor(**kwargs)
if username is None:
username = self.username
curs.execute("select set_config('currentuser.name', %s, false)", [username])
return curs
def __getattr__(self, name):
return getattr(self.conn, name)
def __setattr__(self, name, value):
setattr(self.conn, name, value)
connection = myconnection(database="my_database",
user="my_user",
password="my_password",
host='127.0.0.1')
cursor = connection.cursor(username='michael')
cursor.execute("select current_setting('currentuser.name')")
user = cursor.fetchall()[0][0]
print user
cursor.close()
It correctly prints michael
Upvotes: 3