Если вы пытаетесь использовать dict
для указания как имен столбцов, так и значений, вы не можете этого сделать, по крайней мере, напрямую.
Это действительно присуще SQL. Если вы не укажете список имен столбцов, вы должны указать их в порядке CREATE TABLE
, чего нельзя сделать с dict
, потому что dict
не имеет порядка. Конечно, если вы действительно этого хотите, вы можете использовать collections.OrderedDict
, убедиться, что они в правильном порядке, а затем просто передать values.values()
. Но в таком случае, почему бы сразу не поставить list
(или tuple
)? Если вы абсолютно уверены, что получили все значения в правильном порядке, и хотите обращаться к ним по порядку, а не по имени, у вас есть list
, а не dict
.
И нет способа связать имена столбцов (или имена таблиц и т. д.) в SQL, только значения.
Вы можете, конечно, сгенерировать оператор SQL динамически. Например:
columns = ', '.join(values.keys())
placeholders = ', '.join('?' * len(values))
sql = 'INSERT INTO Media ({}) VALUES ({})'.format(columns, placeholders)
values = [int(x) if isinstance(x, bool) else x for x in values.values()]
cur.execute(sql, values)
Однако это почти всегда плохая идея. На самом деле это ненамного лучше, чем генерация и exec
инг динамического кода Python. И вы только что потеряли все преимущества использования заполнителей в первую очередь — в первую очередь защиту от атак с внедрением SQL, но также и менее важные вещи, такие как более быстрая компиляция, лучшее кэширование и т. д. в механизме БД.
Вероятно, лучше сделать шаг назад и посмотреть на эту проблему с более высокого уровня. Например, может быть, вам нужен не статический список свойств, а таблица "имя-значение" MediaProperties
? Или, в качестве альтернативы, может быть, вам нужно какое-то хранилище на основе документов (будь то мощная система nosql или просто набор объектов JSON или YAML, хранящихся в shelve
)?
Альтернативный вариант с использованием именованных заполнителей:
columns = ', '.join(my_dict.keys())
placeholders = ':'+', :'.join(my_dict.keys())
query = 'INSERT INTO my_table (%s) VALUES (%s)' % (columns, placeholders)
print query
cur.execute(query, my_dict)
con.commit()
01.01.2013
execute
заменяет каждый именованный заполнитель поиском его имени в качестве ключа вmy_dict
. Поэтому однозначно должно бытьkeys
, а неvalues
. Представьте, чтоmy_dict = {'spam': 'eggs'}
. Если вы поместите заполнитель:eggs
в оператор SQL, его не будет вmy_dict
; вам нужно:spam
. 21.05.2015because a dict has no order
... начиная с Python 3.7 в словаре теперь есть порядок.https://mail.python.org/pipermail/python-dev/2017-December/151283.html
31.12.2019