Im trying to set a value in my table with a given ID. When I run this code I am getting a return code of 1 on 'cursor.execute(updateStr)' the first time I run it, but it executes without issue and returns 0 when I run it a second time. There is no exception raised and I am not sure how to retrieve the actual error message. What could cause this problem and how do I dig deeper into the actual error? Thanks for looking.
updateStr = "UPDATE db.table SET OverrideVal = '{0}' WHERE table.OverrideID ={1};".format(overrideVal, overrideID)
returnCode = cursor.execute(updateStr)
if returnCode == 0:
cursor.execute("COMMIT")
else:
cursor.execute("ROLLBACK")
I don't think the execute command returns anything meaningful. Python's DB-API 2.0 states this about the execute method:
Return values are not defined.
Did you check to see if your updates are actually working? (Be sure to commit them).
Related
I'm running into some stranger behavior from PYODBC. I have a really simple stored procedure in SQL that does the following:
CREATE PROCEDURE [schema].[procname]
(
#severity VARCHAR(1) = 'I',
#LogMessage VARCHAR(MAX)
)
AS
BEGIN
INSERT INTO [schema].[table]
(col1
,col2)
VALUES
(#severity
,#LogMessage
)
IF #severity IN ('E','F')
BEGIN;
THROW 320000, #msg, 1
END
END
GO
As you can see, whatever is passed to the parameters is simply inserted into a table. Whenever the #severity is 'E' or 'F', it should throw an error (after inserting).
Now this works fine just calling the procedure in SQL Server Management Studio:
EXEC [schema].[procname] #severity='E', #LogMessage = 'XYZ'
It will return an error, but the record is inserted.
But whenever I call the procedure from PYODBC:
pyodbc_cursor.execute(f"EXEC [schema].[procname] #severity='E', #LogMessage = 'XYZ'")
pyodbc_cursor.commit()
I only get the error, and the record is NOT inserted.
I can't explain this behavior. Does someone have any idea what could be wrong?
Thanks in advance!
You should not use throw to pass information back from your stored procedure, if that is what you want then let the procedure return information like this for example
IF #severity IN ('E','F')
BEGIN
--THROW 320000, #msg, 1
select #msg as result
END
else
begin
select 'no errors' as result
end
and then just read the result of the procedure after calling it.
And then you can still throw an exception in your python code should you whish so
Python uses autocommit=false, so the driver will execute SET IMPLICIT_TRANSACTIONS ON;. This means that the whole batch is inside a transaction by default. When you throw an error it gets rolled back, removing the insert.
Either set autocommit=true in the connection settings, or use another method to return error messages.
Background
In my code below I have a function called process that does some stuff and when it is running i want to make sure it is not run concurrently. I have a table called creation_status where i set a time stamp anytime i start the process. The reason i use a time stamp is because it allows me to know what time i started this process in case i need to.
I always check if there is already a time stamp and if there is raise an exception to make sure i am not running this script concurrently.
Code
def is_in_process() -> bool:
status = db.run_query(sql="SELECT is_in_process FROM creation_status")
return False if status[0].is_in_process is None else True
def set_status() -> None:
db.execute(sql="UPDATE creation_status SET is_in_process = NOW()")
def delete_status() -> None:
db.execute(sql="UPDATE creation_status SET is_in_process = NULL")
def process():
if is_in_process():
raise Exception("Must not run concurrent process creations." )
set_status()
# stuff happens
delete_status()
Issue
I want to make sure my query is atomic to eliminate race conditions. It is possible that the by the time i check the function is_in_process and call the function set_status another script could get kicked off. How do i ensure both those things happen in one go so i avoid race conditions.
Please let me know if i can explain something more clear and i am open to all suggestions.
Don't use multiple steps when you don't need to.
UPDATE creation_status SET is_in_process = NOW() where is_in_process is null returning is_in_process
Then check to see if a row is returned.
Of course this should probably be done in the same transaction as the rest of the stuff, which we can't tell from your code, but then things will just block until the previous is done, rather than aborting.
So I am changing a value inside my database on my website. I am sure it is getting changed. I am printing the value
computer.directory_response = "example" # not the actual value it's always changing
db.session.commit()
print(computer.directory_response)
I can see the printed value in the console. meanwhile, I have a program that sends a request to /computers/1/ajax-dir. the problem in the code is when I am doing a while loop to check if the value is example (to be sure I just implemented the if statement inside the while loop)
while(computer.directory_response == ""):
if computer.directory_response != "":
break
else:
pass
at the beginning it's empty. Yes. But even when I change the value in the first part of code I showed you it's still in the while loop. I don't understand why it doesn't change I am using flask as a backend language
It seems that you aren't adding the computer to the db.session.
As that's the case you should add this before the db.commit():
db.session.add(computer)
So I have a script that isn't quite working yet but I am hoping to get it to a point where it keeps trying to connect to a server until it finally succeeds (using the paramiko library). In simplistic terms, this is what my code is like:
canConnect = False
while canConnect == False:
try:
stdin, stdout, stderr = ssh.exec_command('ps')
if stdout.read():
canConnect = True
else:
# cannot connect
time.sleep(20)
except:
# cannot connect
time.sleep(20)
Now... this would be quite basic for a simple if statement but gets more complicated because I need to use "try" and "except". If the code can connect successfully (using "ps" as a random command that returns content and will prove the server is connectable), I assume it passes into the if condition that then sets canConnect to True and stops the loop. If it cannot connect, I think Paramiko will throw an exception (I put the "else" command there just in case), but once it hits the "except", it should wait for 20 seconds and then I assume the while statement will take the code back to the beginning and start again? What I have witnessed so far is that some kind of loop is happening, but it doesn't actually appear to be attempting to connect to the server.
Also, an unrelated question, documentation is scarce but I assume Paramiko /has/ to take 3 arguments like that to perform an exec_command (regardless of variables assigned, they will take standard output In, Out, Err in that order?)? I also assume it is uncommon to assign multiple comma-delimited variables to something like that, besides lists or method calls?
I think your use of except: may be masking the real problem, as it catches all exceptions, and disregards them. That would explain the some kind of loop is happening, but it doesn't actually appear to be attempting to connect to the server behavior. consider changing that to something like:
except (paramiko.SSHException, socket.error)
I am beginner.I'm running a task in Celery and getting this strange error
maximum recursion depth exceeded while calling a Python object
You can check the full error in this pastebin
I don't quite understand because I haven't change anything and yesterday it was working fine. I ran the task without celery in the python interpreter and it runs fine. You can check the function here. Finally, for what it is worth, this task is getting created 12 times by an other task.
Do you see anything that could create such an error?
EDIT:
This is the task I call this function / task
#celery.task(ignore_result=True)
def get_classicdata(leagueid):
print "getting team data for %s"%leagueid
returned_data = {}
for team in r.smembers('league:%s'%leagueid):
data = scrapteam.delay(team,r.get('currentgw'))
returned_data[team] = data.get()
Everything looks fine. The traceback implies that the returned object somewhere cannot be pickled, but your returned 'team' data structure is a dictionary containing a non-recursive data structure of basic types, so that can't cause a problem. For better remote debugging, please put a print statement before the "return team", so that it shows the content of the team. You might also try just having it return a {} and see if that changes thing.
Then also add a debugging print statement in get_classicdata showing the content of data.get(), as well as something just before the return there, in order to verify if that function reaches completion.