Sybpydb error 5701 ignored sometimes - python

I have come across a very strange behavior when developing an application in Python (2.7.11) using a Sybase ASE 15.7 database and the sybpydb library.
When selecting data from the database there is always an error 5701 thrown that isn´t an error but just a informational message taht the client has logged on or changed database.
This should be ignored by the client and it works fine most of the time but sometimes not.
Has anyone come across this problem and know a way to work around it?
I don´t want to stop handling exceptions.
The following code illustrates the problem, the first two queries runs as the should but the last one doesn´t work, I have checked the query and yes it returns a result set.
uname = 'username'
pwd = 'password'
server = 'server'
conn = sybpydb.connect(user=uname, password=pwd, servername=server)
cur = conn.cursor()
try:
sql = 'select * from database..table1'
cur.execute(sql)
print 'Execute for table1'
print cur.connection.errors()
row = cur.fetchone()
print "Query Returned %d row(s)" % cur.rowcount
print row
except sybpydb.Error:
print cur.connection.errors()
finally:
cur.close()
conn.close()
conn = sybpydb.connect(user=uname, password=pwd, servername=server)
cur = conn.cursor()
parameter1 = 'DSE'
try:
sql = 'select * from database..table2 where column1 = ?'
cur.execute(sql, [parameter1])
print 'Execute for table2'
print cur.connection.errors()
row = cur.fetchone()
print "Query Returned %d row(s)" % cur.rowcount
print row
except sybpydb.Error:
print cur.connection.errors()
finally:
cur.close()
conn.close()
parameter1 = 1
parameter2 = 1
conn = sybpydb.connect(user=uname, password=pwd, servername=server)
cur = conn.cursor()
try:
sql = 'select * from database..table3 where column1 = ? and column2 ?'
cur.execute(sql, [parameter1, parameter2])
print 'Execute for table3'
print cur.connection.errors()
row = cur.fetchone()
print "Query Returned %d row(s)" % cur.rowcount
print row
except sybpydb.Error:
print cur.connection.errors()
finally:
cur.close()
conn.close()
These three calls to the database results in this.
Execute for table1
[DatabaseError("Server message: number(5701) severity(10) state(2) line(0)\n\tChanged database context to 'master'.\n\n", 5701)]
Query Returned -1 row(s)
(Resultset for query 1)
Execute for table2
[DatabaseError("Server message: number(5701) severity(10) state(2) line(0)\n\tChanged database context to 'master'.\n\n", 5701)]
Query Returned -1 row(s)
(Resultset for query2)
[DatabaseError("Server message: number(5701) severity(10) state(2) line(0)\n\tChanged database context to 'master'.\n\n", 5701)]

I never get such message when using sybpydb , I don't print cur.connection.errors() , which is not one of the documented methods (I even got an error when I tried to use it )
In all cases ,maybe you are getting this message as part of Sybase ASE informing the client about:
1- Default database when you log in - I don't think this applied to python .
2- when you change the database context .. which you are doing by specifying "database.."
To get rid of this message , simply set a default database for the user you use to connect as the target database , hence , you connection will be located immediately in that database after login and you don't need to specify the database in the query anymore , to change default database for login use :
sp_modifylogin <uname>, defdb, "<database>"
or in ASE 15.7 :
alter login <uname> modify default database <database>
then your queries should look like :
sql = 'select * from table3 where column1 = ? and column2 ?'

Related

cx_Oracle: select query following an insert produces no result

in my python code I insert a value into a table.
In the table, there is a sequence which automatically assigns an ID.
After the insert, I want to get this it back in to my python application:
import cx_Oracle, sys
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
with conn.cursor() as cur:
cur.execute("Insert into my_table columns(data) values ('Hello')")
conn.commit()
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
with conn.cursor() as cur:
r = cur.execute("select id from my_table where data = 'Hello'")
print(r)
if r is None:
print("Cannot retrieve ID")
sys.exit()
Unfortunately, the result set r is always "None" even though the value has been inserted properly (checked via sqldeveloper).
What am I doing wrong?
I even open a new connection to be sure to grab the value...
After calling execute() for a SELECT statement you need to call fetchone(), fetchmany() or fetchall() as shown in the cx_Oracle documentation SQL Queries.
Or you can use an iterator:
with connection.cursor() as cursor:
try:
sql = """select systimestamp from dual"""
for r in cursor.execute(sql):
print(r)
sql = """select 123 from dual"""
(c_id,) = cursor.execute(sql).fetchone()
print(c_id)
except oracledb.Error as e:
error, = e.args
print(sql)
print('*'.rjust(error.offset+1, ' '))
print(error.message)
However to get an automatically generated ID returned without the overhead of an additional SELECT, you can change the INSERT statement to use a RETURNING INTO clause. There is an example in the cx_Oracle documentation DML RETURNING Bind Variables that shows an UPDATE. You can use similar syntax with INSERT.
With the table:
CREATE TABLE mytable
(myid NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
mydata VARCHAR2(20));
You can insert and get the generated key like:
myidvar = cursor.var(int)
sql = "INSERT INTO mytable (mydata) VALUES ('abc') RETURNING myid INTO :bv"
cursor.execute(sql, bv=myidvar)
i, = myidvar.getvalue()
print(i)
If you just want a unique identifier you get the ROWID of an inserted row without needing a bind variable. Simple access cursor.lastrowid after executing an INSERT.

Why I got an error when I want to count the frequency of data for multiple table in mysql? Flask is used to create web app

I want to create a dashboard widget in my web app. The first step is to count the frequency of pos, neg and neu in mysql from two table. I tried to find the solution in Flask, but not many. Hope u can help me.
The error that I got is:
MySQLdb._exceptions.OperationalError: (1241, 'Operand should contain 1 column(s)')
Table in mysql:
ques9
ques10
My code:
#app.route('/we/<string:programid>')
def we(programid):
# Create cursor
cur = mysql.connection.cursor()
result = """SELECT(
(SELECT programid,sentiment, COUNT(*)
FROM ques9 AS question9
WHERE programid= %s
GROUP BY sentiment),
(SELECT programid,q10_sentiment, COUNT(*)
FROM ques10 AS question10
WHERE programid=%s
GROUP BY q10_sentiment ))"""
data_tuple = (programid, programid)
cur.execute(result, data_tuple)
program = cur.fetchall()
mysql.connection.commit()
if result > 0:
return render_template('we.html',program=program)
else:
msg = 'No Results Found'
return render_template('we.html', msg=msg)
# Close connection
cur.close()
The group by has to be after the where clause
So i posted all the python code, i thought about adding a try, but that you can look up
Your sql has some problems like the group an his own,l but your python code has also flaws, as you can see below. The variables for sql query and the data to send, i out there so that it looks somewhat cleanber
connection = mysql.connector.connect(host='localhost',
database='test_db',
user='user',
password='password')
cur = connection.cursor(prepared=True)
sql_update_query = """SELECT(
(SELECT programid,sentiment, COUNT(*)
FROM ques9 AS question9
WHERE programid= %s
GROUP BY sentiment),
(SELECT programid,q10_sentiment, COUNT(*)
FROM ques10 AS question10
WHERE programid=%s
GROUP BY q10_sentiment ))"""
data_tuple = (programid, programid)
cur .execute(sql_update_query, data_tuple)
connection.commit()
if (connection.is_connected()):
cur.close()
connection.close()

InternalError: (1054, u"Unknown column 'Ihe' in 'where clause'")

Below is a part of my python/pymysql code. I'm basically trying to retrieve data from a database using the input typed into a search box. I don't understand why the data typed in is coming across with this error. "Ihe" is simply a test hostname in my the database.
#app.route('/result',methods= ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form['hostname']
cursor = connection.cursor()
query = ("SELECT * FROM StoryData WHERE hostName LIKE %s" % ( result))
cursor.execute(query)
search_for = cursor.fetchall()
for row in search_for:
ID = row['ID']
hName = row['hostName']
rName = row['reportName']
return render_template("result.html", search_for=search_for)
connection.close()
As written, this is a very dangerous SQL Injection vulnerability.
What happens when I submit a POST request with hostname set to
''; DROP TABLE StoryData;
?
Use parameterized queries instead of using Python string formatting. Assuming your paramstyle is format, you can pass the parameters to execute():
query = "SELECT * FROM StoryData WHERE hostName LIKE %s"
cursor.execute(query, (result, ))

Execute SQL for different where clause from Python

I am trying to print SQL result through python code, where I an trying to pass different predicates of the where clause from a for loop. But the code only taking the last value from the loop and giving the result.
In the below example I have two distinct id values 'aaa' and 'bbb'. There are 4 records for id value = 'aaa' and 2 records for the id value = 'bbb'.
But the below code only giving me the result for the id value ='bbb' not for id value 'aaa'
Can anyone help to identify what exactly wrong I am doing?
import pymysql
db = pymysql.connect(host="localhost", user="user1", passwd="pass1", db="db1")
cur = db.cursor()
in_lst=['aaa', 'bbb']
for i in in_lst:
Sql = "SELECT id, val, typ FROM test123 Where id='{inpt}'".format(inpt=i)
print(Sql)
cur.execute(Sql)
records = cur.fetchall()
print(records)
db.close()
The result I am getting as below
C:\Python34\python.exe C:/Users/Koushik/PycharmProjects/Test20161204/20170405.py
SELECT id, val, typ FROM test123 Where id='bbb'
(('bbb', 5, '1a'), ('bbb', 17, '1d'))
Process finished with exit code 0
import pymysql
db = pymysql.connect(host="localhost", user="root", passwd="1234", db="sakila")
cur = db.cursor()
in_lst=['1', '2']
for i in in_lst:
Sql = "SELECT * FROM actor Where actor_id='{inpt}'".format(inpt=i)
print(Sql)
cur.execute(Sql)
records = cur.fetchall()
print(records)
db.close()
Indentation is your problem, please update the code according to your needs...
Within your for loop, you're formatting the sql statement to replace "{inpt}" with "aaa". However, before you do anything with that value, you're immediately overwriting it with the "bbb" version.
You would need to either:
Store the results somehow before the next iteration of the loop, then process them outside of the loop.
Process the results within the loop.
Something like the following will give you a list containing both results from the fetchall() calls:
import pymysql
db = pymysql.connect(host="localhost", user="user1", passwd="pass1", db="db1")
cur = db.cursor()
in_lst=['aaa', 'bbb']
records = list()
for i in in_lst:
Sql = "SELECT id, val, typ FROM test123 Where id='{inpt}'".format(inpt=i)
print(Sql)
cur.execute(Sql)
records.append(cur.fetchall())
print(records)
db.close()

mysql is showing error in the syntax

I am having trouble in executing this query in python. I have an IP database which has 3 column startip, endip and country. Now I want to the location of the ip. this is my code
def get_country(ip):
try:
conn = MySQLConnection(host='localhost', database='ipdb', user ='root', password='password')
cursor = conn.cursor()
query = 'SELECT * FROM db6 WHERE %s BETWEEN INET_ATON(startip) AND INET_ATON(endip)'
ip_inint= ip2int(ip)
cursor.execute(query,ip_inint)
row = cursor.fetchone()
while row is not None:
print " Start range %s end range %s country %s " %(row[0], row[1], row[2])
row = cursor.fetchone()
except Error as error:
print(error)
ip2int function is
def ip2int(addr):
return struct.unpack("!I", socket.inet_aton(addr))[0]
error i am receiving is
1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s BETWEEN INET_ATON(startip) AND INET_ATON(endip)' at line 1
what could be the issue?
You need to pass a tuple to execute():
cursor.execute(query, (ip_inint,))
A list will probably work too:
cursor.execute(query, [ip_inint])
An alternative is to use a dictionary with named variables in the query:
query = 'SELECT * FROM db6 WHERE %(ip_inint)s BETWEEN INET_ATON(startip) AND INET_ATON(endip)'
cursor.execute(query, {'ip_inint': ip_inint})
Reference: http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

Categories