передача словаря в качестве параметра для mysql.connector - PullRequest
0 голосов
/ 09 июля 2019

У меня был полуработающий, небезопасный набор функций для mysql.connector, который может принимать данные в форме, подобной приведенной ниже. Это гибко, так как я мог создать любой размер словаря, который мне нужен.

db_data={
"column01" : 'test',
"column02" : 51,
"column03" : None
}
columns = db_data.keys()
values = db_data.values()
tablename = "mytable"

Он "работает" нормально, но небезопасно (хотя это только для внутреннего использования, поэтому я не заботился о безопасности здесь), но я также не могу передать "None" (нулевой объект) в mysql.

unsafe_query = "INSERT INTO {0:s} ({1:s}) VALUES ({2:s})".format(tablename, ', '.join(map(str, columns)), ','.join(map(repr, values)))
cursor.execute(unsafe_query)

Я получу ошибку:

Something went wrong: 1054 (42S22): Unknown column 'None' in 'field list'

Следуя предложению о том, как это должно быть правильно спроектировано, я попробовал этот способ, но я не могу заставить форматирование строк передавать словарь таким же образом, и я немного застрял здесь:

safe_query = "INSERT INTO %s (%s) VALUES (%s)"
cursor.execute(safe_query, (tablename, ', '.join(map(repr, columns)), ', '.join(map(repr, values))) )
# cursor.execute(safe_query, (tablename, ', '.join(map(str, columns)), ', '.join(map(str, values))) ) # this won't work either

Получение ошибки:

Something went wrong: 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 ''mytable' ('\'column01\', \'column02\', \'column03\'') VALUES ('\'test\', ' at line 1

Может быть, кто-то может подсказать, как обойти это и заставить работать объект MySQL Null. В идеале должен быть правильный и безопасный запрос, но это не самая важная проблема для меня.

1 Ответ

1 голос
/ 09 июля 2019

Возможно, вы хотите, чтобы ваши значения обрабатывались драйвером, а все остальное составляется в виде строки:

query = "INSERT INTO {} ({}) VALUES ({})".format(tablename, ', '.join(columns), ','.join(['%s']*len(values)))
cursor.execute(query, values)

Еще лучше, вы можете использовать dict напрямую:

query = "INSERT INTO {} ({}) VALUES ({})".format(tablename, ', '.join(columns), ','.join(['%({})s'.format(colname) for colname in columns]))
cursor.execute(query, db_data)

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

...