<p>如果试图使用<code>dict</code>同时指定列名和值,则不能这样做,至少不能直接这样做。</p>
<p>这是SQL的固有特性。如果不指定列名列表,则必须按<code>CREATE TABLE</code>顺序指定列名,而不能按<code>dict</code>顺序指定,因为<code>dict</code>没有顺序。当然,如果您真的想,可以使用<code>collections.OrderedDict</code>,确保它的顺序正确,然后传递<code>values.values()</code>。但在这一点上,为什么不首先有一个<code>list</code>(或者<code>tuple</code>)?如果您绝对确定您已经按照正确的顺序获得了所有的值,并且希望按顺序而不是按名称引用它们,那么您所拥有的是一个<code>list</code>,而不是一个<code>dict</code>。</p>
<p>在SQL中没有办法绑定列名(或表名等),只有值。</p>
<p>当然,您可以动态生成SQL语句。例如:</p>
<pre><code>columns = ', '.join(values.keys())
placeholders = ', '.join('?' * len(values))
sql = 'INSERT INTO Media ({}) VALUES ({})'.format(columns, placeholders)
cur.execute(sql, values.values())
</code></pre>
<p>然而,这几乎总是一个坏主意。这实际上并不比生成和<code>exec</code>使用动态Python代码要好多少。而且您刚刚失去了使用占位符的所有好处,首先主要是防止SQL注入攻击,但也失去了在DB引擎中更快的编译、更好的缓存等不太重要的东西。</p>
<p>最好是退后一步,从更高的层次来看待这个问题。例如,也许您并不真正想要一个静态的属性列表,而是一个名称值<code>MediaProperties</code>表?或者,或者,您可能需要某种基于文档的存储(无论是高性能的nosql系统,还是存储在<code>shelve</code>中的一堆JSON或YAML对象)?</p>
<hr/>
<p>使用<a href="http://docs.python.org/2.7/library/sqlite3.html#sqlite3.Cursor.execute">named placeholders</a>的替代方法:</p>
<pre><code>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()
</code></pre>