I am teaching myself python and have a function called mysqltimedcheck()
This executes a very basic mySQL SELECT statement and returns the rowcount.
If i cange the value of 'shown' from 0 to 1 in the mysql table (while the script is running) for example the rowcount does not change.
I can see when debugging that it reruns the cursor.execute line again but still prints an old value
here is my function:
def mysqltimedcheck():
cursor = mydb.cursor(buffered=True)
window.after(1500, mysqltimedcheck)
cursor.execute("SELECT * FROM alerts WHERE shown = 0")
rc = cursor.rowcount
print(rc)
If i restart my test application then it pulls the correct rowcount value but changing this value while running does not show as correct.
I feel im missing something very basic.
Thanks for your help
All credit to #LabibaKanij
adding mydb.commit() worked correctly and allowed me to change the value in the table and it changed for my script without restarting.
Related
Using Python and SQlite3 where c is a cursor this code...
print("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
print("SQL and parameters:",sql,parm)
c.execute(sql,parm)
# Get the row
print("Executed OK")
response = c.fetchone()
# If not successful return null
if not response:
return None
#
print("and produced ", response)
print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
give this output:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
SQL and parameters: select * from Links where LinkNum = ? (301,)
Executed OK
and produced (301, 'Index', 'The Independent', 'https://www.independent.co.uk/', 6, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
SQL and parameters: select * from Links where LinkNum = ? (301,)
Encountered exception of type ProgrammingError with arguments ('Incorrect number of bindings supplied. The current statement uses 1, and there are 6 supplied.',)
The application will close
Two identical statements. 1 works and the next throws the exception. As can be seen the row I'm trying to retrieve has 6 columns but that's the only hint/clue I can see. Can anyone help with tracking down the problem? Thanks.
Whatever was causing SQLite to have a fit I remedied the problem by retrieving the second row/object out side the Links object and passing it as an argument to the method I was calling, rather than have that method attempt to retrieve the object.
The problem would still be there but must be deep within the internals of Python instantiation and/or SQLite. Whatever, this problem is solved with some less fancy code.
So I have an issue very similar to this question, but a bit different.
I am calling cursor.execute(sqlString) on a piece of sql that works fine when I run it directly on the mysql workbench. When I run the code however I get no result set.
I have exactly the same issue symptons as stated in the link and I have tried the linked solutions but it turns out that I do not have the same issue.
my _stored_results[] is empty when returning.
I am using the code in a try/except block, I have another python program that uses the same code to load a csv into a my mySQL db and it works dandy.
The code where I am having the issue is within an #app.route if that makes any differnce.
My code looks like this:
def functionName() :
try:
import mysql.connector
from mysql.connector import errorcode
cnx = mysql.connector.connect(user=init["dbDetails"][0], password=init["dbDetails"][1], host=init["dbDetails"][2], database=init["dbDetails"][3])
cur = cnx.cursor()
cur.close() #I deffo don't need the two lines below but they were added for a sanity check, just to make sure the cur was not being read from any other code.
cur = cnx.cursor() # and this one obviously
sqlString = 'CALL `schemaName`.`getProcedureName_sp`(1, 1, 0)'
cur.execute(sqlString, multi=True) # tried it here without the multi=True and got the msg telling me to use it.
getSomeDetails = cur.fetchall()
cnx.commit() # probably don't need to commit here I am just reading from the dB but I am trying anything as I have no idea what my issue might be.
return render_template('success.html')
except Exception as e:
return render_template('error.html', error = str(e))
finally:
cur.close()
cnx.close()
I am so baffled as I have this same code working in several places.
So I was beating my head against the wall with this, and when I couldn't get anywhere, I just decided to leave it and move on, then come back with a fresh mind. Well... It worked, kinda.
So I haven't found the solution but I have found a work around that does the job and might even shed some light as to what is actually happening in my code.
I decided that as the fetchall() method was what was causing me the trouble I should try to circumvent it.
I probed the cursor(cur) just before the fetchall() method was called and saw that cur._rows contains the results from the SQL call.
So I changed the line
getSomeDetails = cur.fetchall()
to
if len(cur._rows) > 0 :
getSomeDetails = list(cur._rows[0]) #I only ever expect one result in this query
#getSomeDetails should now have the row I am looking for
getSomeDetails[0] #gets me the field I am looking for
and now my variable getSomeDetails has the return values from the procedure call
They are however not in the nice format that I should have gotten them from the fetchall() function, so I had to do some processing, I had to ensure that I was getting some values back and I noted that these values were returned in a tuple
I have come across this issue on two different machines running two different OS's and two different versions of python (Windows 7 with Python 2.7 and Windows 10 with Python 3) both pieces of code were different so obviously infact I was using two different MySQL libraries so the actual code for the fix was slightly different in both cases but I am now in both cases getting data from my DB into variables in Python, so that's cool.
However, this is a hack and I am aware of that, I would rather be using the proper function cur.fetchall() so I am still open to suggestions of what could be going wrong here.
I have the following code:
conn = pymssql.connect(server, user, password, database)
cursor = conn.cursor()
id_new_field = pymssql.output(int)
res = cursor.callproc('NewField', ('Test',id_new_field))
conn.commit()
conn.close()
print(id_new_field.value)
print(res)
Unfortunately my output parameter isn't populated with the id of the field, although the stored procedure is executed correctly. The output ist always 'None'.
I think the problem is, that autocommit ist set to false in my example, am i right?
But i can't set autocommit to true because the stored procedure is raising an error when it isn't executed inside a transaction (It's a vendor SP and i can't alter the SP).
So, my workarount for now is, to use .execute() instead of .callproc() and writing raw sql into my python script. It's awful. ;)
Is there any chance to use .callproc() with autocommit = false?
Or do i have to do it completely different?
I also got None when I did
print(id_new_field.value)
but I was able to retrieve the value by simply indexing into res tuple:
print(res[1])
(Tested with Python 2.7.11 and pymssql 2.1.1.)
I am attempting to call a sproc that wraps T-SQL's sp_send_dbmail procedure. It simply creates the query, and then passes that and a hardcoded subject and recipient to the Microsoft supplied sproc. When running from sql management studio, the sproc executes as expected and I receive an email. From pyodbc, it doesn't send an email. The contents of my sproc look similar to:
declare #qry varchar(MAX)
set #qry = 'select * from table'
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'email#email.com',
#subject = 'my email',
#query = #qry
select * from table
where 1=0
I have also tried toggling the #exclude_query_output, flag but that had no effect. I am invoking that sproc via the following method:
def execute_sproc(query, cnxn):
cursor = cnxn.cursor();
rows = cursor.execute(query)
columns = [column[0] for column in cursor.description]
return pd.DataFrame.from_records(rows, columns=columns)
where the query is simply executing my wrapper sproc. As I mentioned before, the wrapper sproc works when run from the management studio, but no email is sent when called here. I am using the same credentials to access my database in both places. I have also used this function to successfully call other sprocs, but none of them have contained exec statements, nor have they done many of the other things that im sure sp_send_dbmail is doing.
Please let me know if you have any ideas.
Thanks,
Max Goldman
So i think this comes down to a misunderstanding of either the sendmail sproc, pyodbc, or both. I have another method for calling sprocs that edit the database:
def execute_commit_sproc(query, cnxn):
cursor = cnxn.cursor();
cursor.execute(query)
cnxn.commit()
The only difference being that the former expected a result set, whereas the latter makes changes to the db, and uses pyodbc's commit mechanism to save the results. I did not realize the sp_send_dbmail required this to be called in order for the email to be sent. I am still unsure of why (what is getting written to, what pyodbc::commit() is doing under the hood, etc.)
This SQL Alchemy 0.9.7 code executes without error -- but does not update the underlying database as expected.
Here is the python:
print t #prints TITLE ABSTRACTOR 1
print newtitle #prints TITLE ABSTRACTOR I
print session.query(Basic).filter(Basic.title==t).count() #prints 1
ret = update(Basic).where(Basic.title==t).values(title=newtitle)
session.commit()
Here is what the database looks like after the update:
select count(*) from basics where title='TITLE ABSTRACTOR 1';
count
-------
1
(1 row)
select count(*) from basics where title='TITLE ABSTRACTOR I';
count
-------
0
(1 row)
Have I hit a SQL alchemy bug or am I missing something?
You're just constructing an update statement:
ret = update(Basic).where(Basic.title==t).values(title=newtitle)
That doesn't do anything unless you execute the statement:
stmt = update(Basic).where(Basic.title==t).values(title=newtitle)
ret = conn.execute(stmt)
But I think you were trying to use the ORM interface, not the core interface. In which case, although I don't remember the details, I'm pretty sure you do that by modifying a query object, not by calling anything named update. Hopefully if this is what you're looking for, hopefully someone who's fresher on this will provide a better answer, but something like this:
ret = session.query(Basic).filter(Basic.title==t)
ret.title = newtitle
If this doesn't make sense to you, see Executing in the tutorial. But I'm guessing you know this and it was just one of those stupid bugs we all make and all have a hard enough time seeing in other people's code, and it's 100x worse in our own. :)