#python #mysql #python-3.x #stored-procedures
#python #mysql #python-3.x #хранимые процедуры
Вопрос:
У меня есть mysql proc:
CREATE DEFINER=`user`@`localhost` PROCEDURE `mysproc`(INOUT par_a INT(10), IN par_b VARCHAR(255) , IN par_c VARCHAR(255), IN par_etc VARCHAR(255))
BEGIN
// bla... insert query here
SET par_a = LAST_INSERT_ID();
END$$
DELIMITER ;
чтобы проверить этот sp, если я запущу:
SET @par_a = -1;
SET @par_b = 'one';
SET @par_c = 'two';
SET @par_etc = 'three';
CALL mysproc(@par_a, @par_b, @par_c, @par_etc);
SELECT @par_a;
COMMIT;
он возвращает @par_a как то, что я хочу, поэтому я предполагаю, что моя БД в порядке…
затем…
У меня есть python следующим образом:
import pymysql.cursors
def someFunction(self, args):
# generate Query
query = "SET @par_a = %s;
CALL mysproc(@par_a, %s, %s, %s);
SELECT @par_a
commit;"
try:
with self.connection.cursor() as cursor:
cursor.execute(query,(str(par_a), str(par_b), str(par_c), str(par_etc)))
self.connection.commit()
result = cursor.fetchone()
print(result) # <-- it print me 'none' how do i get my @par_a result from mysproc above?
return result
except:
raise
finally:
self.DestroyConnection()
результат: сохраненный процесс выполнен, как я вижу запись.
проблема: но я не могу получить результат @par_a в моем коде python из mysproc выше?
и, если я изменю:
# generate Query
query = "SET @par_a = '" str(-1) "';
CALL mysproc(@par_a, %s, %s, %s);
SELECT @par_a
commit;"
Для
# generate Query
query = "SELECT 'test'
commit;"
и
cursor.execute(query)
как ни странно, это дает мне правильный результат ('test',)
Комментарии:
1. Вы используете
cursor.fetchall()
илиcursor.fetchone()
. Вам следует потратить немного времени на чтение документации здесь: pymysql.readthedocs.io/en/latest2. Спасибо, @Nicarus, нужно ли мне делать «select» в моей переменной запроса в python, чтобы получить результат par_a? или fetchone() будет достаточно умен, чтобы получить мой результат par_a? пока я пытался, python напечатал мне ‘none’ T_T
3. Вам нужно, чтобы запрос возвращал нужные значения. Как только запрос записан для этого, вы используете функции выборки, чтобы вернуть этот результат в Python.
4. @Nicarus, не работает, я обновил свой вопрос и изменил ваш образец документа, но результат продолжает посылать мне «нет»
5. Почему вы пишете свой запрос выше иначе, чем приведенный ниже???
Ответ №1:
Я использовал этот класс и получил ответ.
import pymysql.cursors
class connMySql:
def __init__(self, User, Pass, DB, Host='localhost', connShowErr=False, connAutoClose=True):
self.ShowErr = connShowErr
self.AutoClose = connAutoClose
self.DBName = DB
try:
self.connection = pymysql.connect(host=Host,
user=User,
password=Pass,
db=DB, #charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
def Fetch(self, Query):
try:
with self.connection.cursor() as cursor:
# Read a single record
cursor.execute(Query)
result = cursor.fetchall()
return result
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
finally:
if self.AutoClose == True: self.connection.close()
def Insert(self, Query):
try:
with self.connection.cursor() as cursor:
# Create a new record
cursor.execute(Query)
# connection is not autocommit by default. So you must commit to save
# your changes.
self.connection.commit()
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
finally:
if self.AutoClose == True: self.connection.close()
def ProcedureExist(self, ProcedureName):
try:
result = self.Fetch("SELECT * FROM mysql.proc WHERE db = "" str(self.DBName) "";")
Result = []
for item in result:
Result.append(item['name'])
if ProcedureName in Result:
return True
else:
return False
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
def CallProcedure(ProcedureName, Arguments=""):
try:
# Set arguments as a string value
result = self.Fetch('CALL ' ProcedureName '(' Arguments ')')
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
finally:
if self.AutoClose == True: self.connection.close()
def CloseConnection(self):
try:
self.connection.close()
return True
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
def main():
objMysqlConn = connMySql('user', '1234', 'myDB', connShowErr=True, connAutoClose=False)
ProcedureName= "mysproc"
if objMysqlConn.ProcedureExist(ProcedureName):
result = objMysqlConn.Fetch('CALL ' ProcedureName '()')
if result != False:
result = result[0]
print(result)
else:
print("The procecure does not exist!")
if __name__ == '__main__':
main()