Как распечатать запрос, отправляемый в mySQL, с помощью pymysql?

Скажем, у меня есть следующий код:

with open('saved_response.json') as data_file: 
    #data_ordered = json.load(data_file, object_pairs_hook=OrderedDict)
    response=json.load(data_file)

for user_data in response['itemList']:
    field_names = ""
    field_values=[]
    for i in user_data:
        field_names+ = ","+i
        field_values.append(user_data[i])
    print(field_names[1:])
    print(field_values)
    with con.cursor() as c:
        c.execute("INSERT into user(%s) values(%s);",(field_names[1:],field_values))

Я получаю следующую ошибку:

ProgrammingError: (1064, "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 ''id,parentId,username,creationTime,role,state,userProfile') values((562949953421' at line 1")

Есть ли способ распечатать SQL-запрос, отправляемый в MySQL для выполнения, чтобы мы могли устранить подобные синтаксические ошибки? Также будет оценено решение этой ошибки.

Вы видели stackoverflow.com/questions/7071166/…?

ChatterOne 04.07.2018 16:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
1 450
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

with open('saved_response.json') as data_file: 
    #data_ordered = json.load(data_file, object_pairs_hook=OrderedDict)
    response=json.load(data_file)

for user_data in response['itemList']:
    field_names=[]
    field_values=[]
    for i in user_data:
        field_names.append(i)
        field_values.append(user_data[i])
    print(field_names)
    print(field_values)
    with con.cursor() as c:
        c.execute("INSERT into user(%s) values(%s);",(','.join(field_names), ','.join(str(field) for field in field_values)))

Проблема заключалась в том, что вы передавали список в %s. Вы должны разделить field_values ​​запятыми.

Ответ принят как подходящий

Как указано в комментариях, объекты курсора PyMySQL также имеют недокументированный атрибут _last_executed, который содержит отправленный запрос.

Ваши синтаксические ошибки являются результатом попытки передать идентификаторы, в данном случае имена столбцов, с использованием заполнителей. Из сообщения об ошибке видно, что

'id,...,userProfile') values((...

было отправлено. Другими словами, столбцы были отправлены как один (строковый) литерал. К сожалению, для передачи идентификаторов нельзя использовать заполнители. В этом случае требуется построение строки запроса. Вы должны внести столбцы в белый список, а затем построить свой запрос.

Предложение VALUES также проблематично из-за двойных скобок. Оказывается, PyMySQL умеет кодировать последовательности, передаваемые как «скалярные» аргументы:

In [65]: with conn.cursor() as cur:
    ...:     cur.execute('select %s in %s',
    ...:                 ('z', ['\');DROP TABLE students -- ', 'x', 'y']))
    ...:     print(cur.fetchone())
    ...:     print(cur._last_executed)
    ...:     
(0,)
select 'z' in ('\');DROP TABLE students -- ','x','y')

Поэтому вместо того, чтобы заключать заполнитель списка значений в скобки, просто поместите заполнитель там, где должен быть список значений.

ALLOWED_COLUMNS = {'id', 'parentId', 'username', 'creationTime',
                   'role', 'state', 'userProfile'}

for user_data in response['itemList']:
    field_names, field_values = zip(*user_data.items())

    unknown = set(field_names) - ALLOWED_COLUMNS
    if unknown:
        raise RuntimeError(f"Unknown columns: {unknown}")

    field_names = ','.join(field_names)

    with con.cursor() as c: 
        # Note: field names have been whitelisted. Normally one should avoid
        # string formatting SQL queries.
        c.execute(f"INSERT INTO user ({field_names}) VALUES %s", (field_values,))

В заключение, если в ваших столбцах действительно используется смешанный регистр и они были созданы как таковые, вам, возможно, придется их процитировать.

Другие вопросы по теме