How can I print postgres's stored procedure on python script?
Example of stored procedure in postgres is as below:
create or replace function checktime() returns void
language plpgsql
as $$
DECLARE timestart TIMESTAMP;
FOR id from rt LOOP
SELECT timeofday() into timestart;
RAISE NOTICE 'Time now : %', timestart;
END LOOP;
END;
$$
;
From python, my script is:
import psycopg2
conn = psycopg2.connect(host="", database="",
user="", password="")
print("Database Connected")
cur = conn.cursor()
rowcount = cur.rowcount
cur.callproc('rt_visits_function_gz')
# how can i display the raise notice in here?
I would like for each loop the result is displayed when i run python.
Thank you
Try using 'notices'
print(conn.notices)
http://initd.org/psycopg/docs/connection.html?highlight=notice#connection.notices
Related
I have an issue with $$ in psycopg2 library. For testing purposes I've created simple code snippet like
CREATE OR REPLACE PROCEDURE test()
AS $$
BEGIN
select 1;
END
$$ LANGUAGE plpgsql;
and if I process it in any postgresql client it's all fine, but processing in psycopg causes unterminated dollar-quoted string at or near "$$...
Any idea how to fix it?
It works for me doing:
import psycopg2
con = psycopg2.connect(dbname="test", host='localhost', user='postgres')
proc_sql = """CREATE OR REPLACE PROCEDURE test()
AS $$
BEGIN
select 1;
END
$$ LANGUAGE plpgsql;"""
cur = con.cursor()
cur.execute(proc_sql)
con.commit()
I got some python code (psycopg2) with which should insert data into a database:
def debug(self):
try:
self.connection.execute(
"SELECT test();")
res = self.connection.fetchall()
print(res)
except Exception as e:
print(e)
return
The test() function in pgsql is this:
CREATE OR REPLACE FUNCTION test(
) RETURNS setof varchar
AS $Body$
BEGIN
INSERT INTO Linie(name) VALUES('3');
RETURN QUERY(SELECT * FROM linie);
END;
$Body$ LANGUAGE plpgsql;
When i change the "name" value and execute the query in pgAdmin there is a now entry in the database. However when calling the function from python it always overrides the value.
The table is defined as follows:
CREATE TABLE Linie(
name varchar,
PRIMARY KEY (name)
);
For example with pgAdmin i can insert 1,2,3,4,5.
With python after running 5 equivalent queries it is just 5.
Calling the test function with nodeJS works fine.
When calling the function once from python then changing the insert value and then calling it from python again, the values are not replaced but inserted.
Also it does not throw any errors and returns the table as it should (except the replaced value).
why is this happening and what can i do against it?
Psycopg2 by default will not commit changes made to the database unless you explicitly call connection.commit() after executing your SQL. You could alter you code like so:
def debug(self):
try:
self.connection.execute(
"SELECT test();")
res = self.connection.fetchall()
self.connection.commit()
print(res)
except Exception as e:
print(e)
return
However, please be careful doing this as I have no information on what exactly self.connection is an instance of, therefore I have assumed it to be of type connection :)
Alternatively, when you setup your connection to the DB, set the property autocommit to True, as documented here. Example:
self.connection = psycopg2.connect(user='foo', password='bar', host='localhost', dbname='mydb')
self.connection.autocommit = True
If you are already using autocommit let me know and I'll have another look at your question.
I would like to pass a local variable from MySQL to python using MySQLdb module.
I know there are a lot of answers about the other way around (from python to mysql), and I am not looking for that.
I know also how to get any data from a table using
SELECT data_name
FROM table_name
The affected rows can be fetched to get the result.
However, running a SELECT #my_variable from python returns an empty result.
LOCK TABLES `usedID` WRITE;
/...*Do some stuff here*/
SELECT `lastaugID` FROM `usedID` INTO #ID;
UNLOCK TABLES;
SELECT #ID;
Executing the above snippet from mysql returns the expected result:
+-------+
| #ID |
+-------+
| 58404 |
+-------+
1 row in set (0.00 sec)
But the passed value to python is an empty list.
Here is the python snippet making SQL query:
def write_sql(self, sqlreq, sqlreqdict):
if self.sockname:
con = MySQLdb.Connect( unix_socket=self.sockname, user=self.sqluser,
passwd=self.sqlpasswd, db=self.sqldb,
cursorclass=MySQLdb.cursors.DictCursor );
else:
con = MySQLdb.Connect( host=self.sqlhost, user=self.sqluser,
passwd=self.sqlpasswd, db=self.sqldb,
cursorclass=MySQLdb.cursors.DictCursor );
cursor = con.cursor();
try:
cursor.execute( sqlreq, sqlreqdict );
except MySQLdb.IntegrityError, val:
html.print_errmsg_exit( "Database integrity error: " + str(val) );
res = cursor.fetchall();
del cursor;
con.commit();
con.close();
# Re-open the read-only cursors of the DB, to be able to process
# a request to read the just-created file:
self.init_db();
return res
PS: Why not just read from the table directly? I need to lock the table and read the value before it is unlocked. If I read after unlocking, I might get a value that has been changed by another session.
Stored Procedure :
CREATE OR REPLACE FUNCTION try_create() RETURNS INT AS $$
BEGIN
CREATE TABLE hello(id SERIAL PRIMARY KEY, name TEXT);
RETURN 1;
END ;
$$ LANGUAGE plpgsql;
test.py
import psycopg2
conn = psycopg2.connect(user='a', password='a', dbname='a')
cur = conn.cursor()
cur.callproc('try_create', ())
print cur.fetchall()
I am trying to create a stored procedure which will create a table named hello. I am invoking the same using a python script. Upon running the above script I see the following output
[root#localhost partitioning]# python test.py
[(1,)]
But the table is not created at the db. Am I making something wrong here? Thanks.
You should commit the transaction, add the commands:
...
conn.commit()
conn.close()
Alternatively, you can set the connection in autocommit mode:
conn = psycopg2.connect(user='a', password='a', dbname='a')
conn.autocommit = True
cur = conn.cursor()
cur.callproc('try_create', ())
conn.close()
Read more about transactions in psycopg2.
I'm trying to call stored procedure from MySQL and obtain OUT param.
I have code like this one,
Call procedure from Python
from django.db import connection
# ...
cursor = connection.cursor()
out_arg1 = ""
args = [in_arg1, in_arg2, out_arg1]
result = cursor.callproc('some_procedure', args)
print(args[2], result[2])
cursor.close()
# ...
MySQL procedure
CREATE DEFINER=`root`#`localhost` PROCEDURE `some_procedure`(IN `in_arg1` VARCHAR(255) CHARSET utf8, IN `in_arg2` VARCHAR(255) CHARSET utf8, OUT `out_arg1` VARCHAR(255) CHARSET utf8)
MODIFIES SQL DATA
BEGIN
proc:begin
set out_arg1="Result";
end;
END;
I've checked args and the result returned by cursor.callproc method, but no data changed.
Any ideas why this is happening?
Thanks in advance.
P.S. I've tried to call this procedure from MySQL console and everything is ok.
use this way
from django.db import connection
# ...
cursor = connection.cursor()
out_arg1 = ""
args = [in_arg1, in_arg2, out_arg1]
result = cursor.callproc('some_procedure', args)
cursor.execute('SELECT #some_procedure_2')
print(cursor.fetchall())
#print(args[2], result[2])
cursor.close()
# ...