uTools-Manuals/docs/python/sqlite3.html
2019-04-21 11:50:48 +08:00

485 lines
140 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="body" role="main"><div class="section" id="module-sqlite3"><h1><span class="yiyi-st" id="yiyi-10">12.6. <a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a> - SQLite数据库的DB-API 2.0接口</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/sqlite3/">Lib / sqlite3 /</a></span></p><p><span class="yiyi-st" id="yiyi-12">SQLite 是一个C库它提供了一个轻量级的基于磁盘的数据库它不需要一个单独的服务器进程并允许使用非标准的SQL查询语言的变体访问数据库。</span><span class="yiyi-st" id="yiyi-13">一些应用程序可以使用SQLite来存储内部数据。</span><span class="yiyi-st" id="yiyi-14">也可以使用SQLite来建立应用原型随后再将代码移植到大型的数据库比如PostgreSQL或者Oracle。</span></p><p><span class="yiyi-st" id="yiyi-15">sqlite3模块由Gerhard Häring编写。</span><span class="yiyi-st" id="yiyi-16">它提供了一个SQL接口该接口和<a class="pep reference external" href="https://www.python.org/dev/peps/pep-0249"><strong>PEP 249</strong></a>描述的<span class="target" id="index-0">DB-API 2.0规范</span>兼容。</span></p><p><span class="yiyi-st" id="yiyi-17">若要使用该模块,必须首先创建一个表示数据库的<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>对象。</span><span class="yiyi-st" id="yiyi-18">这里的数据将存储在<code class="file docutils literal"><span class="pre">example.db</span></code>文件:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">'example.db'</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-19">也可以使用特殊名称<code class="docutils literal"><span class="pre">:memory:</span></code>以在 RAM内存中创建数据库。</span></p><p><span class="yiyi-st" id="yiyi-20">一旦有了一个<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>,就可以创建<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">Cursor</span></code></a>对象并调用其<a class="reference internal" href="#sqlite3.Cursor.execute" title="sqlite3.Cursor.execute"><code class="xref py py-meth docutils literal"><span class="pre">execute()</span></code></a>方法来执行 SQL 命令:</span></p><pre><code class="language-python"><span></span><span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="c1"># Create table</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'''CREATE TABLE stocks</span>
<span class="s1"> (date text, trans text, symbol text, qty real, price real)'''</span><span class="p">)</span>
<span class="c1"># Insert a row of data</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)"</span><span class="p">)</span>
<span class="c1"># Save (commit) the changes</span>
<span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
<span class="c1"># We can also close the connection if we are done with it.</span>
<span class="c1"># Just be sure any changes have been committed or they will be lost.</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-21">保存过的数据是持久的并在以后的会话中可用:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">'example.db'</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-22">通常的SQL操作需要使用Python变量中的值。</span><span class="yiyi-st" id="yiyi-23">你不应该使用Python的字符串操作来组合查询因为这样做是不安全的它使你的程序容易受到SQL注入攻击参见<a class="reference external" href="https://xkcd.com/327/">https://xkcd.com/327/</a>,这是关于可能出错的幽默例子)。</span></p><p><span class="yiyi-st" id="yiyi-24">相反,应该使用 DB API 参数替代。</span><span class="yiyi-st" id="yiyi-25">放置<code class="docutils literal"><span class="pre">?</span></code></span><span class="yiyi-st" id="yiyi-26">作为占位符,只要您想要使用值,然后提供一个元组值作为光标的<a class="reference internal" href="#sqlite3.Cursor.execute" title="sqlite3.Cursor.execute"><code class="xref py py-meth docutils literal"><span class="pre">execute()</span></code></a>方法的第二个参数。</span><span class="yiyi-st" id="yiyi-27">(其他的数据库模块可能使用不同的占位符,如<code class="docutils literal"><span class="pre">%s</span></code><code class="docutils literal"><span class="pre">:1</span></code>。)</span><span class="yiyi-st" id="yiyi-28">举个例子:</span></p><pre><code class="language-python"><span></span><span class="c1"># Never do this -- insecure!</span>
<span class="n">symbol</span> <span class="o">=</span> <span class="s1">'RHAT'</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"SELECT * FROM stocks WHERE symbol = '</span><span class="si">%s</span><span class="s2">'"</span> <span class="o">%</span> <span class="n">symbol</span><span class="p">)</span>
<span class="c1"># Do this instead</span>
<span class="n">t</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'RHAT'</span><span class="p">,)</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'SELECT * FROM stocks WHERE symbol=?'</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">fetchone</span><span class="p">())</span>
<span class="c1"># Larger example that inserts many records at a time</span>
<span class="n">purchases</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'2006-03-28'</span><span class="p">,</span> <span class="s1">'BUY'</span><span class="p">,</span> <span class="s1">'IBM'</span><span class="p">,</span> <span class="mi">1000</span><span class="p">,</span> <span class="mf">45.00</span><span class="p">),</span>
<span class="p">(</span><span class="s1">'2006-04-05'</span><span class="p">,</span> <span class="s1">'BUY'</span><span class="p">,</span> <span class="s1">'MSFT'</span><span class="p">,</span> <span class="mi">1000</span><span class="p">,</span> <span class="mf">72.00</span><span class="p">),</span>
<span class="p">(</span><span class="s1">'2006-04-06'</span><span class="p">,</span> <span class="s1">'SELL'</span><span class="p">,</span> <span class="s1">'IBM'</span><span class="p">,</span> <span class="mi">500</span><span class="p">,</span> <span class="mf">53.00</span><span class="p">),</span>
<span class="p">]</span>
<span class="n">c</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="s1">'INSERT INTO stocks VALUES (?,?,?,?,?)'</span><span class="p">,</span> <span class="n">purchases</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-29">为了取回<a class="reference internal" href="../glossary.html#term-iterator"><span class="xref std std-term">iterator</span></a>语句的执行结果你可以把游标cursor 当做是一个迭代器,通过调用游标的<a class="reference internal" href="#sqlite3.Cursor.fetchone" title="sqlite3.Cursor.fetchone"><code class="xref py py-meth docutils literal"><span class="pre">fetchone()</span></code></a>方法来获取单行结果;或者通过调用<a class="reference internal" href="#sqlite3.Cursor.fetchall" title="sqlite3.Cursor.fetchall"><code class="xref py py-meth docutils literal"><span class="pre">fetchall()</span></code></a>方法获取结果集列表。</span></p><p><span class="yiyi-st" id="yiyi-30">此示例使用迭代器形式:</span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'SELECT * FROM stocks ORDER BY price'</span><span class="p">):</span>
<span class="go"> print(row)</span>
<span class="go">('2006-01-05', 'BUY', 'RHAT', 100, 35.14)</span>
<span class="go">('2006-03-28', 'BUY', 'IBM', 1000, 45.0)</span>
<span class="go">('2006-04-06', 'SELL', 'IBM', 500, 53.0)</span>
<span class="go">('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)</span>
</code></pre><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-31">请参见</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-32"><a class="reference external" href="https://github.com/ghaering/pysqlite">https://github.com/ghaering/pysqlite</a></span></dt><dd><span class="yiyi-st" id="yiyi-33">pysqlite网页 - sqlite3是在名称“pysqlite”外部开发的。</span></dd><dt><span class="yiyi-st" id="yiyi-34"><a class="reference external" href="https://www.sqlite.org">https://www.sqlite.org</a></span></dt><dd><span class="yiyi-st" id="yiyi-35">SQLite网页该文档描述了支持的SQL方言的语法和可用的数据类型。</span></dd><dt><span class="yiyi-st" id="yiyi-36"><a class="reference external" href="http://www.w3schools.com/sql/">http://www.w3schools.com/sql/</a></span></dt><dd><span class="yiyi-st" id="yiyi-37">学习SQL语法的教程参考和示例。</span></dd><dt><span class="yiyi-st" id="yiyi-38"><span class="target" id="index-1"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0249"><strong>PEP 249</strong></a> - 数据库API规范2.0</span></dt><dd><span class="yiyi-st" id="yiyi-39">PEP由Marc-AndréLemburg编写。</span></dd></dl></div><div class="section" id="module-functions-and-constants"><h2><span class="yiyi-st" id="yiyi-40">12.6.1. </span><span class="yiyi-st" id="yiyi-41">Module functions and constants</span></h2><dl class="data"><dt id="sqlite3.version"><span class="yiyi-st" id="yiyi-42"> <code class="descclassname">sqlite3.</code><code class="descname">version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-43">该模块的字符串形式的版本号。</span><span class="yiyi-st" id="yiyi-44">这不是 SQLite 库的版本。</span></p></dd></dl><dl class="data"><dt id="sqlite3.version_info"><span class="yiyi-st" id="yiyi-45"> <code class="descclassname">sqlite3.</code><code class="descname">version_info</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-46">该模块的整数元组形式的版本号。</span><span class="yiyi-st" id="yiyi-47">这不是 SQLite 库的版本。</span></p></dd></dl><dl class="data"><dt id="sqlite3.sqlite_version"><span class="yiyi-st" id="yiyi-48"> <code class="descclassname">sqlite3.</code><code class="descname">sqlite_version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-49">运行期SQLite库的版本号字符串形式。</span></p></dd></dl><dl class="data"><dt id="sqlite3.sqlite_version_info"><span class="yiyi-st" id="yiyi-50"> <code class="descclassname">sqlite3.</code><code class="descname">sqlite_version_info</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-51">运行期SQLite库的版本号整数元组形式。</span></p></dd></dl><dl class="data"><dt id="sqlite3.PARSE_DECLTYPES"><span class="yiyi-st" id="yiyi-52"> <code class="descclassname">sqlite3.</code><code class="descname">PARSE_DECLTYPES</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-53">该常量用于<a class="reference internal" href="#sqlite3.connect" title="sqlite3.connect"><code class="xref py py-func docutils literal"><span class="pre">connect()</span></code></a>函数的<em>detect_types</em>参数。</span></p><p><span class="yiyi-st" id="yiyi-54">设置它使得<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块解析每个返回列的声明的类型。</span><span class="yiyi-st" id="yiyi-55">它将解析出声明的类型的第一个单词,比如,"integer primary key",它将解析出"integer",而"number(10)",它将解析出"number"。</span><span class="yiyi-st" id="yiyi-56">然后对于那列,它将查询转换器字典并对类型使用对应注册的转换器函数。</span></p></dd></dl><dl class="data"><dt id="sqlite3.PARSE_COLNAMES"><span class="yiyi-st" id="yiyi-57"> <code class="descclassname">sqlite3.</code><code class="descname">PARSE_COLNAMES</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-58">该常量用于<a class="reference internal" href="#sqlite3.connect" title="sqlite3.connect"><code class="xref py py-func docutils literal"><span class="pre">connect()</span></code></a>函数的<em>detect_types</em>参数。</span></p><p><span class="yiyi-st" id="yiyi-59">设置它使得SQLite接口解析每个返回列的列名。</span><span class="yiyi-st" id="yiyi-60">它将查找[mytype]形式的字符串,然后决定'mytype'是列的类型。</span><span class="yiyi-st" id="yiyi-61">将会尝试在转换器字典中找到对应于'mytype'的转换器,然后将转换器函数应用于返回的值。</span><span class="yiyi-st" id="yiyi-62"><a class="reference internal" href="#sqlite3.Cursor.description" title="sqlite3.Cursor.description"><code class="xref py py-attr docutils literal"><span class="pre">Cursor.description</span></code></a>中找到的的列名只是列名的第一个单词如果SQL中有类似<code class="docutils literal"><span class="pre">'as</span> <span class="pre">"x</span> <span class="pre">[datetime]"'</span></code>的成分,那么第一个单词将会被解析成列名,直到有空格为止:列名只是简单的"x"。</span></p></dd></dl><dl class="function"><dt id="sqlite3.connect"><span class="yiyi-st" id="yiyi-63"> <code class="descclassname">sqlite3.</code><code class="descname">connect</code><span class="sig-paren">(</span><em>database</em><span class="optional">[</span>, <em>timeout</em>, <em>detect_types</em>, <em>isolation_level</em>, <em>check_same_thread</em>, <em>factory</em>, <em>cached_statements</em>, <em>uri</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-64">打开到SQLite数据库文件<em>database</em>的连接。</span><span class="yiyi-st" id="yiyi-65">可以使用<code class="docutils literal"><span class="pre">":memory:"</span></code>打开到内存的数据库的连接。</span></p><p><span class="yiyi-st" id="yiyi-66">当多个连接访问数据库其中一个进程修改了数据库SQLite数据库会锁定直到事务被提交。</span><span class="yiyi-st" id="yiyi-67"><em>timeout</em>参数指明为了得到锁,连接最多等待多久,如果等待超时则抛出异常。</span><span class="yiyi-st" id="yiyi-68">超时参数的默认值是 5.0 5 秒)。</span></p><p><span class="yiyi-st" id="yiyi-69">对于<em>isolation_level</em>参数,请参阅<a class="reference internal" href="#sqlite3.Connection.isolation_level" title="sqlite3.Connection.isolation_level"><code class="xref py py-attr docutils literal"><span class="pre">Connection.isolation_level</span></code></a>对象的<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>属性。</span></p><p><span class="yiyi-st" id="yiyi-70">SQLite 原生只支持文本、 整数、 实数BLOB 和 NULL类型。</span><span class="yiyi-st" id="yiyi-71">如果您想要使用其他类型,必须自己添加对它们的支持。</span><span class="yiyi-st" id="yiyi-72"><em>detect_types</em>参数和使用由<a class="reference internal" href="#sqlite3.register_converter" title="sqlite3.register_converter"><code class="xref py py-func docutils literal"><span class="pre">register_converter()</span></code></a>函数注册的自定义<strong>转换器</strong>使得这很容易。</span></p><p><span class="yiyi-st" id="yiyi-73"><em>detect_types</em>默认为 0 (即关闭,没有类型检测),你可以将它设置为<a class="reference internal" href="#sqlite3.PARSE_DECLTYPES" title="sqlite3.PARSE_DECLTYPES"><code class="xref py py-const docutils literal"><span class="pre">PARSE_DECLTYPES</span></code></a><a class="reference internal" href="#sqlite3.PARSE_COLNAMES" title="sqlite3.PARSE_COLNAMES"><code class="xref py py-const docutils literal"><span class="pre">PARSE_COLNAMES</span></code></a>的任意组合以打开类型检测。</span></p><p><span class="yiyi-st" id="yiyi-74">默认情况下,<em>check_same_thread</em><a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>,只有创建线程可以使用连接。</span><span class="yiyi-st" id="yiyi-75">如果设置为<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a>,则返回的连接可以跨多个线程共享。</span><span class="yiyi-st" id="yiyi-76">当使用具有相同连接的多个线程时,写入操作应该由用户序列化以避免数据损坏。</span></p><p><span class="yiyi-st" id="yiyi-77">默认情况下, <a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块使用<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>类以调用connect。</span><span class="yiyi-st" id="yiyi-78">然而,可以继承<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>类,通过将子类提供给<em>factory</em>参数,使得<a class="reference internal" href="#sqlite3.connect" title="sqlite3.connect"><code class="xref py py-func docutils literal"><span class="pre">connect()</span></code></a>使用你的子类。</span></p><p><span class="yiyi-st" id="yiyi-79">有关详细信息,请参阅该手册的<a class="reference internal" href="#sqlite3-types"><span>SQLite and Python types</span></a>的章节。</span></p><p><span class="yiyi-st" id="yiyi-80"><a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块内部使用语句缓存来避免 SQL 解析开销。</span><span class="yiyi-st" id="yiyi-81">如果想要显式设置连接所缓存的语句的数量,可以设置<em>cached_statements</em>参数。</span><span class="yiyi-st" id="yiyi-82">在当前实现中的默认设置是缓存 100 条语句。</span></p><p><span class="yiyi-st" id="yiyi-83">如果<em>uri</em>为真,则<em>数据库</em>被解释为URI。</span><span class="yiyi-st" id="yiyi-84">这允许您指定选项。</span><span class="yiyi-st" id="yiyi-85">例如,要以只读模式打开数据库,您可以使用:</span></p><pre><code class="language-python"><span></span><span class="n">db</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">'file:path/to/database?mode=ro'</span><span class="p">,</span> <span class="n">uri</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-86">有关此功能的详细信息(包括已识别选项的列表),请参见<a class="reference external" href="https://www.sqlite.org/uri.html">SQLite URI文档</a></span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-87"><span class="versionmodified">在版本3.4中已更改:</span>添加了<em>uri</em>参数。</span></p></div></dd></dl><dl class="function"><dt id="sqlite3.register_converter"><span class="yiyi-st" id="yiyi-88"> <code class="descclassname">sqlite3.</code><code class="descname">register_converter</code><span class="sig-paren">(</span><em>typename</em>, <em>callable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-89">注册可调用对象用来将来自数据库的bytestring转换成为自定义的Python类型。</span><span class="yiyi-st" id="yiyi-90">对数据库所有有<em>typename</em>类型的值调用该可调用对象。</span><span class="yiyi-st" id="yiyi-91">参见<a class="reference internal" href="#sqlite3.connect" title="sqlite3.connect"><code class="xref py py-func docutils literal"><span class="pre">connect()</span></code></a>函数的<em>detect_types</em>参数以了解类型检测是如何工作的。</span><span class="yiyi-st" id="yiyi-92">请注意<em>typename</em>的大小写和查询中类型的名称必须匹配 </span></p></dd></dl><dl class="function"><dt id="sqlite3.register_adapter"><span class="yiyi-st" id="yiyi-93"> <code class="descclassname">sqlite3.</code><code class="descname">register_adapter</code><span class="sig-paren">(</span><em>type</em>, <em>callable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-94">注册可调用对象用来将自定义的 Python 类型<em>type</em>转换为 SQLite 的支持的类型。</span><span class="yiyi-st" id="yiyi-95">可调用<em>可调用</em>接受Python值作为单个参数并且必须返回以下类型的值intfloatstr或bytes。</span></p></dd></dl><dl class="function"><dt id="sqlite3.complete_statement"><span class="yiyi-st" id="yiyi-96"> <code class="descclassname">sqlite3.</code><code class="descname">complete_statement</code><span class="sig-paren">(</span><em>sql</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-97">如果字符串<em>sql</em>包含一个或多个以分号结束的完整的SQL语句则返回<a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a></span><span class="yiyi-st" id="yiyi-98">它不验证SQL的语法正确性只是检查没有未关闭的字符串常量以及语句是以分号结束的。</span></p><p><span class="yiyi-st" id="yiyi-99">这可以用于生成一个 sqlite shell如以下示例所示</span></p><pre><code class="language-python"><span></span><span class="c1"># A minimal SQLite shell for experiments</span>
<span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">isolation_level</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">buffer</span> <span class="o">=</span> <span class="s2">""</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Enter your SQL commands to execute in sqlite3."</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Enter a blank line to exit."</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
<span class="k">if</span> <span class="n">line</span> <span class="o">==</span> <span class="s2">""</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">buffer</span> <span class="o">+=</span> <span class="n">line</span>
<span class="k">if</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">complete_statement</span><span class="p">(</span><span class="n">buffer</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">buffer</span> <span class="o">=</span> <span class="n">buffer</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span>
<span class="k">if</span> <span class="n">buffer</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"SELECT"</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchall</span><span class="p">())</span>
<span class="k">except</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Error</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"An error occurred:"</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">buffer</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">con</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></dd></dl><dl class="function"><dt id="sqlite3.enable_callback_tracebacks"><span class="yiyi-st" id="yiyi-100"> <code class="descclassname">sqlite3.</code><code class="descname">enable_callback_tracebacks</code><span class="sig-paren">(</span><em>flag</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-101">默认情况下你不会在用户定义的函数、 聚合、 转换器、 授权者回调等地方得到回溯对象(调用栈对象)。</span><span class="yiyi-st" id="yiyi-102">如果想要调试它们,将<em>flag</em>设置为<code class="docutils literal"><span class="pre">True</span></code>调用此函数。</span><span class="yiyi-st" id="yiyi-103">之后可以在<code class="docutils literal"><span class="pre">sys.stderr</span></code>通过回调得到回溯。</span><span class="yiyi-st" id="yiyi-104">使用<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a>来再次禁用该功能。</span></p></dd></dl></div><div class="section" id="connection-objects"><h2><span class="yiyi-st" id="yiyi-105">12.6.2. </span><span class="yiyi-st" id="yiyi-106">Connection Objects</span></h2><dl class="class"><dt id="sqlite3.Connection"><span class="yiyi-st" id="yiyi-107"> <em class="property">class </em><code class="descclassname">sqlite3.</code><code class="descname">Connection</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-108">SQLite 数据库连接具有以下的属性和方法:</span></p><dl class="attribute"><dt id="sqlite3.Connection.isolation_level"><span class="yiyi-st" id="yiyi-109"> <code class="descname">isolation_level</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-110">获取或设置当前隔离级别。</span><span class="yiyi-st" id="yiyi-111"><a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>为自动提交模式;或者为"DEFERRED"、"IMMEDIATE"或"EXCLUSIVE"之一。</span><span class="yiyi-st" id="yiyi-112">参见<a class="reference internal" href="#sqlite3-controlling-transactions"><span>Controlling Transactions</span></a>章节以得到更详细的解释。</span></p></dd></dl><dl class="attribute"><dt id="sqlite3.Connection.in_transaction"><span class="yiyi-st" id="yiyi-113"> <code class="descname">in_transaction</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-114"><a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>如果交易处于活动状态(有未提交的更改),则<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a></span><span class="yiyi-st" id="yiyi-115">只读属性。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-116"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="sqlite3.Connection.cursor"><span class="yiyi-st" id="yiyi-117"> <code class="descname">cursor</code><span class="sig-paren">(</span><span class="optional">[</span><em>cursorClass</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-118">游标方法接受单个可选参数<em>cursorClass</em></span><span class="yiyi-st" id="yiyi-119">如果提供,这必须是一个扩展<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">sqlite3.Cursor</span></code></a> 的自定义游标类。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.commit"><span class="yiyi-st" id="yiyi-120"> <code class="descname">commit</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-121">此方法提交当前事务。</span><span class="yiyi-st" id="yiyi-122">如果不调用此方法,自上次调用<code class="docutils literal"><span class="pre">commit()</span></code>后做的任何改动对于其它数据库连接不可见。</span><span class="yiyi-st" id="yiyi-123">如果没有看到写入数据库的数据,请检查是否有调用该方法。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.rollback"><span class="yiyi-st" id="yiyi-124"> <code class="descname">rollback</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-125">该方法回滚自从上一次<a class="reference internal" href="#sqlite3.Connection.commit" title="sqlite3.Connection.commit"><code class="xref py py-meth docutils literal"><span class="pre">commit()</span></code></a>调用之后对数据库所做的任何更改。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.close"><span class="yiyi-st" id="yiyi-126"> <code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-127">这将关闭数据库连接。</span><span class="yiyi-st" id="yiyi-128">请注意这不会自动调用<a class="reference internal" href="#sqlite3.Connection.commit" title="sqlite3.Connection.commit"><code class="xref py py-meth docutils literal"><span class="pre">commit()</span></code></a></span><span class="yiyi-st" id="yiyi-129">如果你关闭数据库连接没有先调用<a class="reference internal" href="#sqlite3.Connection.commit" title="sqlite3.Connection.commit"><code class="xref py py-meth docutils literal"><span class="pre">commit()</span></code></a> ,你的更改将会丢失 </span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.execute"><span class="yiyi-st" id="yiyi-130"> <code class="descname">execute</code><span class="sig-paren">(</span><em>sql</em><span class="optional">[</span>, <em>parameters</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-131">这是一个非正规的缩写,通过调用<a class="reference internal" href="#sqlite3.Connection.cursor" title="sqlite3.Connection.cursor"><code class="xref py py-meth docutils literal"><span class="pre">cursor()</span></code></a>方法创建一个游标对象,使用<em>参数</em>调用游标的<a class="reference internal" href="#sqlite3.Cursor.execute" title="sqlite3.Cursor.execute"><code class="xref py py-meth docutils literal"><span class="pre">execute()</span></code></a></span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.executemany"><span class="yiyi-st" id="yiyi-132"> <code class="descname">executemany</code><span class="sig-paren">(</span><em>sql</em><span class="optional">[</span>, <em>parameters</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-133">这是一个非标准快捷方式,通过调用<a class="reference internal" href="#sqlite3.Connection.cursor" title="sqlite3.Connection.cursor"><code class="xref py py-meth docutils literal"><span class="pre">cursor()</span></code></a>方法创建一个游标对象,使用给定的<em>参数</em>调用游标的<a class="reference internal" href="#sqlite3.Cursor.executemany" title="sqlite3.Cursor.executemany"><code class="xref py py-meth docutils literal"><span class="pre">executemany()</span></code></a></span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.executescript"><span class="yiyi-st" id="yiyi-134"> <code class="descname">executescript</code><span class="sig-paren">(</span><em>sql_script</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-135">这是一个非标准的快捷方式,通过调用<a class="reference internal" href="#sqlite3.Connection.cursor" title="sqlite3.Connection.cursor"><code class="xref py py-meth docutils literal"><span class="pre">cursor()</span></code></a>方法,使用给定的<em>sql_script</em>方法调用游标<a class="reference internal" href="#sqlite3.Cursor.executescript" title="sqlite3.Cursor.executescript"><code class="xref py py-meth docutils literal"><span class="pre">executescript()</span></code></a></span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.create_function"><span class="yiyi-st" id="yiyi-136"> <code class="descname">create_function</code><span class="sig-paren">(</span><em>name</em>, <em>num_params</em>, <em>func</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-137">创建一个自定义的函数随后可以在SQL语句中以函数名<em>name</em>来调用它。</span><span class="yiyi-st" id="yiyi-138"><em>num_params</em>是函数接受的参数数量(如果<em>num_params</em>为-1函数可以取任意数量的参数<em>func</em>一个被称为SQL函数的Python可调用。</span></p><p><span class="yiyi-st" id="yiyi-139">函数可以返回SQLite支持的任何类型bytesstrintfloat和None。</span></p><p><span class="yiyi-st" id="yiyi-140">示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="k">def</span> <span class="nf">md5sum</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
<span class="k">return</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="n">t</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">create_function</span><span class="p">(</span><span class="s2">"md5"</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">md5sum</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select md5(?)"</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="s2">"foo"</span><span class="p">,))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
</code></pre></dd></dl><dl class="method"><dt id="sqlite3.Connection.create_aggregate"><span class="yiyi-st" id="yiyi-141"> <code class="descname">create_aggregate</code><span class="sig-paren">(</span><em>name</em>, <em>num_params</em>, <em>aggregate_class</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-142">创建一个用户定义的聚合函数。</span></p><p><span class="yiyi-st" id="yiyi-143">聚合类必须实现<code class="docutils literal"><span class="pre">step</span></code>方法,该方法接受参数数量<em>num_params</em>(如果<em>num_params</em>为-1的参数和一个<code class="docutils literal"><span class="pre">finalize</span></code>方法,它将返回聚合的最终结果。</span></p><p><span class="yiyi-st" id="yiyi-144"><code class="docutils literal"><span class="pre">finalize</span></code>方法可以返回SQLite支持的任何类型bytesstrintfloat和None。</span></p><p><span class="yiyi-st" id="yiyi-145">示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">class</span> <span class="nc">MySum</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">step</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="n">value</span>
<span class="k">def</span> <span class="nf">finalize</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">create_aggregate</span><span class="p">(</span><span class="s2">"mysum"</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">MySum</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table test(i)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into test(i) values (1)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into test(i) values (2)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select mysum(i) from test"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
</code></pre></dd></dl><dl class="method"><dt id="sqlite3.Connection.create_collation"><span class="yiyi-st" id="yiyi-146"> <code class="descname">create_collation</code><span class="sig-paren">(</span><em>name</em>, <em>callable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-147">用指定的<em>name</em><em>callable</em>创建一个排序规则。</span><span class="yiyi-st" id="yiyi-148">将会传两个字符串参数给可调用对象。</span><span class="yiyi-st" id="yiyi-149">如果第一个比第二个小,返回-1如果它们相等返回0如果第一个比第二个大返回1。</span><span class="yiyi-st" id="yiyi-150">请注意它控制排序SQL里的ORDER BY所以不会影响其它的SQL操作。</span></p><p><span class="yiyi-st" id="yiyi-151">请注意可调用对象将会以Python bytestring的方式得到它的参数一般为UTF-8编码。</span></p><p><span class="yiyi-st" id="yiyi-152">下面的示例演示自定义的排序规则以"错误方式"来排序:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">def</span> <span class="nf">collate_reverse</span><span class="p">(</span><span class="n">string1</span><span class="p">,</span> <span class="n">string2</span><span class="p">):</span>
<span class="k">if</span> <span class="n">string1</span> <span class="o">==</span> <span class="n">string2</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">elif</span> <span class="n">string1</span> <span class="o">&lt;</span> <span class="n">string2</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">create_collation</span><span class="p">(</span><span class="s2">"reverse"</span><span class="p">,</span> <span class="n">collate_reverse</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table test(x)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="s2">"insert into test(x) values (?)"</span><span class="p">,</span> <span class="p">[(</span><span class="s2">"a"</span><span class="p">,),</span> <span class="p">(</span><span class="s2">"b"</span><span class="p">,)])</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select x from test order by x collate reverse"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">cur</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-153">若要删除一个排序规则把None当作可调用对象来调用<code class="docutils literal"><span class="pre">create_collation</span></code></span></p><pre><code class="language-python"><span></span><span class="n">con</span><span class="o">.</span><span class="n">create_collation</span><span class="p">(</span><span class="s2">"reverse"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</code></pre></dd></dl><dl class="method"><dt id="sqlite3.Connection.interrupt"><span class="yiyi-st" id="yiyi-154"> <code class="descname">interrupt</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-155">可以从另一个线程中调用该方法来中止该连接正在执行的查询。</span><span class="yiyi-st" id="yiyi-156">查询会中止,调用者会得到一个异常。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.set_authorizer"><span class="yiyi-st" id="yiyi-157"> <code class="descname">set_authorizer</code><span class="sig-paren">(</span><em>authorizer_callback</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-158">这个例程注册一个回调。</span><span class="yiyi-st" id="yiyi-159">每次尝试访问的数据库中的表的列,则调用该回调。</span><span class="yiyi-st" id="yiyi-160">如果访问被允许,回调应该返回<code class="xref py py-const docutils literal"><span class="pre">SQLITE_OK</span></code>如果SQL语句应该以错误中止回调应该返回<code class="xref py py-const docutils literal"><span class="pre">SQLITE_DENY</span></code>如果列应该被当成NULL值回调应该返回<code class="xref py py-const docutils literal"><span class="pre">SQLITE_IGNORE</span></code></span><span class="yiyi-st" id="yiyi-161">这些常量在<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块中可用</span></p><p><span class="yiyi-st" id="yiyi-162">回调的第一个参数表示何种操作被授权。</span><span class="yiyi-st" id="yiyi-163">根据第一个参数,第二和第三个参数将提供或是<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span><span class="yiyi-st" id="yiyi-164">第四个参数是数据库的名称“main”“temp”等</span><span class="yiyi-st" id="yiyi-165">如果适用。</span><span class="yiyi-st" id="yiyi-166">第5个参数是最内部的触发器或视图的名字它们负责访问请求如果访问请求直接来自于输入的SQL代码则为<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-167">参阅SQlite的文档以了解第一个参数可能的值以及第二个第三个参数依赖于第一个参数的含义。</span><span class="yiyi-st" id="yiyi-168">所有必需的常量在<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块中可用。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.set_progress_handler"><span class="yiyi-st" id="yiyi-169"> <code class="descname">set_progress_handler</code><span class="sig-paren">(</span><em>handler</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-170">这个例程注册一个回调。</span><span class="yiyi-st" id="yiyi-171">SQLite虚拟机每执行<em>n</em>个指令调用该回调。</span><span class="yiyi-st" id="yiyi-172">如果希望在长时间操作过程中从SQLite得到调用这是有用的比如更新GUI。</span></p><p><span class="yiyi-st" id="yiyi-173">如果希望清除之前安装的过程处理器,以<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a><em>handler</em>参数调用该方法。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.set_trace_callback"><span class="yiyi-st" id="yiyi-174"> <code class="descname">set_trace_callback</code><span class="sig-paren">(</span><em>trace_callback</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-175">要为SQLite后端实际执行的每个SQL语句调用寄存器<em>trace_callback</em></span></p><p><span class="yiyi-st" id="yiyi-176">传递给回调的唯一参数是正在执行的语句(作为字符串)。</span><span class="yiyi-st" id="yiyi-177">回调的返回值被忽略。</span><span class="yiyi-st" id="yiyi-178">请注意,后端不仅运行传递到<a class="reference internal" href="#sqlite3.Cursor.execute" title="sqlite3.Cursor.execute"><code class="xref py py-meth docutils literal"><span class="pre">Cursor.execute()</span></code></a>方法的语句。</span><span class="yiyi-st" id="yiyi-179">其他来源包括Python模块的事务管理和在当前数据库中定义的触发器的执行。</span></p><p><span class="yiyi-st" id="yiyi-180"><a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>作为<em>trace_callback</em>传递将禁用跟踪回调。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-181"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="sqlite3.Connection.enable_load_extension"><span class="yiyi-st" id="yiyi-182"> <code class="descname">enable_load_extension</code><span class="sig-paren">(</span><em>enabled</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-183">这个例程允许/不允许 SQLite 引擎从共享库加载 SQLite 扩展。</span><span class="yiyi-st" id="yiyi-184">SQLite 扩展可以定义新的函数、 聚合或全新的虚拟表实现。</span><span class="yiyi-st" id="yiyi-185">有一个知名的扩展是一个和SQLite一起分发的全文搜索扩展。</span></p><p><span class="yiyi-st" id="yiyi-186">默认情况下禁用加载扩展。</span><span class="yiyi-st" id="yiyi-187">请参见<a class="footnote-reference" href="#f1" id="id1">[1]</a></span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-188"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="c1"># enable extension loading</span>
<span class="n">con</span><span class="o">.</span><span class="n">enable_load_extension</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># Load the fulltext search extension</span>
<span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select load_extension('./fts3.so')"</span><span class="p">)</span>
<span class="c1"># alternatively you can load the extension using an API call:</span>
<span class="c1"># con.load_extension("./fts3.so")</span>
<span class="c1"># disable extension laoding again</span>
<span class="n">con</span><span class="o">.</span><span class="n">enable_load_extension</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="c1"># example from SQLite wiki</span>
<span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create virtual table recipe using fts3(name, ingredients)"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">executescript</span><span class="p">(</span><span class="s2">"""</span>
<span class="s2"> insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');</span>
<span class="s2"> insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');</span>
<span class="s2"> insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');</span>
<span class="s2"> insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');</span>
<span class="s2"> """</span><span class="p">)</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select rowid, name, ingredients from recipe where name match 'pie'"</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
</code></pre></dd></dl><dl class="method"><dt id="sqlite3.Connection.load_extension"><span class="yiyi-st" id="yiyi-189"> <code class="descname">load_extension</code><span class="sig-paren">(</span><em>path</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-190">此例程从一个共享库加载 SQLite 扩展。</span><span class="yiyi-st" id="yiyi-191">在使用该方法之前必须用<a class="reference internal" href="#sqlite3.Connection.enable_load_extension" title="sqlite3.Connection.enable_load_extension"><code class="xref py py-meth docutils literal"><span class="pre">enable_load_extension()</span></code></a>来允许扩展加载。</span></p><p><span class="yiyi-st" id="yiyi-192">默认情况下禁用加载扩展。</span><span class="yiyi-st" id="yiyi-193">请参见<a class="footnote-reference" href="#f1" id="id2">[1]</a></span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-194"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="attribute"><dt id="sqlite3.Connection.row_factory"><span class="yiyi-st" id="yiyi-195"> <code class="descname">row_factory</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-196">可以将此属性修改为一可调用对象,该对象接收游标和原始行作为参数,返回真正的结果行。</span><span class="yiyi-st" id="yiyi-197">以这种方式,你可以实现更高级的返回结果的方式,比如返回一个对象,可以通过按列名的方式来访问列。</span></p><p><span class="yiyi-st" id="yiyi-198">示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">def</span> <span class="nf">dict_factory</span><span class="p">(</span><span class="n">cursor</span><span class="p">,</span> <span class="n">row</span><span class="p">):</span>
<span class="n">d</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">col</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">cursor</span><span class="o">.</span><span class="n">description</span><span class="p">):</span>
<span class="n">d</span><span class="p">[</span><span class="n">col</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span>
<span class="k">return</span> <span class="n">d</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">row_factory</span> <span class="o">=</span> <span class="n">dict_factory</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select 1 as a"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="s2">"a"</span><span class="p">])</span>
</code></pre><p><span class="yiyi-st" id="yiyi-199">如果返回元组不够,并且您希望基于名称访问列,则应考虑将<a class="reference internal" href="#sqlite3.Connection.row_factory" title="sqlite3.Connection.row_factory"><code class="xref py py-attr docutils literal"><span class="pre">row_factory</span></code></a>设置为高度优化的<a class="reference internal" href="#sqlite3.Row" title="sqlite3.Row"><code class="xref py py-class docutils literal"><span class="pre">sqlite3.Row</span></code></a>类型。</span><span class="yiyi-st" id="yiyi-200"><a class="reference internal" href="#sqlite3.Row" title="sqlite3.Row"><code class="xref py py-class docutils literal"><span class="pre">Row</span></code></a>提供了基于索引的方式来访问列,也提供了基于大小写无关的名字的方式来访问列,且几乎没有内存的额外开销。</span><span class="yiyi-st" id="yiyi-201">它一般都会比你自定义的基于字典的方案甚至基于db_row的方案要好。</span></p></dd></dl><dl class="attribute"><dt id="sqlite3.Connection.text_factory"><span class="yiyi-st" id="yiyi-202"> <code class="descname">text_factory</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-203">使用此属性可以控制对于<code class="docutils literal"><span class="pre">TEXT</span></code>数据类型,何种对象将会返回。</span><span class="yiyi-st" id="yiyi-204">默认情况下,此属性设置为<a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a>,而<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块将返回<code class="docutils literal"><span class="pre">TEXT</span></code>的Unicode对象。</span><span class="yiyi-st" id="yiyi-205">如果要返回bytestrings可以将其设置为<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-206">也可以将其设置为任意的其它的可调用对象该对象接收单一的bytestring参数返回结果对象。</span></p><p><span class="yiyi-st" id="yiyi-207">请参见下面的演示例子代码:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">AUSTRIA</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\xd6</span><span class="s2">sterreich"</span>
<span class="c1"># by default, rows are returned as Unicode</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select ?"</span><span class="p">,</span> <span class="p">(</span><span class="n">AUSTRIA</span><span class="p">,))</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">AUSTRIA</span>
<span class="c1"># but we can make sqlite3 always return bytestrings ...</span>
<span class="n">con</span><span class="o">.</span><span class="n">text_factory</span> <span class="o">=</span> <span class="nb">bytes</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select ?"</span><span class="p">,</span> <span class="p">(</span><span class="n">AUSTRIA</span><span class="p">,))</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="k">assert</span> <span class="nb">type</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="ow">is</span> <span class="nb">bytes</span>
<span class="c1"># the bytestrings will be encoded in UTF-8, unless you stored garbage in the</span>
<span class="c1"># database ...</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">AUSTRIA</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span>
<span class="c1"># we can also implement a custom text_factory ...</span>
<span class="c1"># here we implement one that appends "foo" to all strings</span>
<span class="n">con</span><span class="o">.</span><span class="n">text_factory</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"foo"</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select ?"</span><span class="p">,</span> <span class="p">(</span><span class="s2">"bar"</span><span class="p">,))</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"barfoo"</span>
</code></pre></dd></dl><dl class="attribute"><dt id="sqlite3.Connection.total_changes"><span class="yiyi-st" id="yiyi-208"> <code class="descname">total_changes</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-209">返回自从数据库连接打开以来,所有的被修改的/添加的/删除的数据行的数目。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Connection.iterdump"><span class="yiyi-st" id="yiyi-210"> <code class="descname">iterdump</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-211">返回一个以SQL文本格式转储数据的迭代器。</span><span class="yiyi-st" id="yiyi-212">保存内存中的数据库,供以后还原时很有用。</span><span class="yiyi-st" id="yiyi-213">此函数提供<strong class="program">sqlite3</strong> shell中<code class="kbd docutils literal"><span class="pre">.dump</span></code>命令相同的功能。</span></p><p><span class="yiyi-st" id="yiyi-214">示例:</span></p><pre><code class="language-python"><span></span><span class="c1"># Convert file existing_db.db to SQL dump file dump.sql</span>
<span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">'existing_db.db'</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'dump.sql'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">con</span><span class="o">.</span><span class="n">iterdump</span><span class="p">():</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="se">\n</span><span class="s1">'</span> <span class="o">%</span> <span class="n">line</span><span class="p">)</span>
</code></pre></dd></dl></dd></dl></div><div class="section" id="cursor-objects"><h2><span class="yiyi-st" id="yiyi-215">12.6.3. </span><span class="yiyi-st" id="yiyi-216">Cursor Objects</span></h2><dl class="class"><dt id="sqlite3.Cursor"><span class="yiyi-st" id="yiyi-217"> <em class="property">class </em><code class="descclassname">sqlite3.</code><code class="descname">Cursor</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-218"><a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">Cursor</span></code></a>实例具有以下的属性和方法。</span></p><dl class="method"><dt id="sqlite3.Cursor.execute"><span class="yiyi-st" id="yiyi-219"> <code class="descname">execute</code><span class="sig-paren">(</span><em>sql</em><span class="optional">[</span>, <em>parameters</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-220">执行一个 SQL 语句。</span><span class="yiyi-st" id="yiyi-221">SQL语句可以参数化即使用占位符而不是SQL字面量</span><span class="yiyi-st" id="yiyi-222"><a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块支持两种类型的占位符问号标记qmark 型) 和命名占位符 (命名样式)。</span></p><p><span class="yiyi-st" id="yiyi-223">这里是两种风格的示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table people (name_last, age)"</span><span class="p">)</span>
<span class="n">who</span> <span class="o">=</span> <span class="s2">"Yeltsin"</span>
<span class="n">age</span> <span class="o">=</span> <span class="mi">72</span>
<span class="c1"># This is the qmark style:</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into people values (?, ?)"</span><span class="p">,</span> <span class="p">(</span><span class="n">who</span><span class="p">,</span> <span class="n">age</span><span class="p">))</span>
<span class="c1"># And this is the named style:</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select * from people where name_last=:who and age=:age"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"who"</span><span class="p">:</span> <span class="n">who</span><span class="p">,</span> <span class="s2">"age"</span><span class="p">:</span> <span class="n">age</span><span class="p">})</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">())</span>
</code></pre><p><span class="yiyi-st" id="yiyi-224"><a class="reference internal" href="#sqlite3.Cursor.execute" title="sqlite3.Cursor.execute"><code class="xref py py-meth docutils literal"><span class="pre">execute()</span></code></a>只执行单个 SQL 语句。</span><span class="yiyi-st" id="yiyi-225">如果您尝试使用它执行多个语句,它将引发<code class="docutils literal"><span class="pre">sqlite3.Warning</span></code></span><span class="yiyi-st" id="yiyi-226">如果想要在一个调用中执行多个 SQL 语句,请使用<a class="reference internal" href="#sqlite3.Cursor.executescript" title="sqlite3.Cursor.executescript"><code class="xref py py-meth docutils literal"><span class="pre">executescript()</span></code></a></span></p></dd></dl><dl class="method"><dt id="sqlite3.Cursor.executemany"><span class="yiyi-st" id="yiyi-227"> <code class="descname">executemany</code><span class="sig-paren">(</span><em>sql</em>, <em>seq_of_parameters</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-228">对在序列<em>seq_of_parameters</em>中找到的所有参数序列或映射执行SQL命令。</span><span class="yiyi-st" id="yiyi-229">除了序列,<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块也允许使用<a class="reference internal" href="../glossary.html#term-iterator"><span class="xref std std-term">iterator</span></a> yield 参数。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">class</span> <span class="nc">IterChars</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="s1">'a'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">__next__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">&gt;</span> <span class="nb">ord</span><span class="p">(</span><span class="s1">'z'</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">StopIteration</span>
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">chr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="p">),)</span> <span class="c1"># this is a 1-tuple</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table characters(c)"</span><span class="p">)</span>
<span class="n">theIter</span> <span class="o">=</span> <span class="n">IterChars</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="s2">"insert into characters(c) values (?)"</span><span class="p">,</span> <span class="n">theIter</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select c from characters"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchall</span><span class="p">())</span>
</code></pre><p><span class="yiyi-st" id="yiyi-230">这里是使用一种<a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator</span></a>的更短的示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="kn">import</span> <span class="nn">string</span>
<span class="k">def</span> <span class="nf">char_generator</span><span class="p">():</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">string</span><span class="o">.</span><span class="n">ascii_lowercase</span><span class="p">:</span>
<span class="k">yield</span> <span class="p">(</span><span class="n">c</span><span class="p">,)</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table characters(c)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="s2">"insert into characters(c) values (?)"</span><span class="p">,</span> <span class="n">char_generator</span><span class="p">())</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select c from characters"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchall</span><span class="p">())</span>
</code></pre></dd></dl><dl class="method"><dt id="sqlite3.Cursor.executescript"><span class="yiyi-st" id="yiyi-231"> <code class="descname">executescript</code><span class="sig-paren">(</span><em>sql_script</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-232">这是一次执行多个 SQL 语句的非标准的便捷方法。</span><span class="yiyi-st" id="yiyi-233">它先发出<code class="docutils literal"><span class="pre">COMMIT</span></code>语句,然后执行作为参数的 SQL 脚本。</span></p><p><span class="yiyi-st" id="yiyi-234"><em>sql_script</em>可以是<a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a>的实例。</span></p><p><span class="yiyi-st" id="yiyi-235">示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">executescript</span><span class="p">(</span><span class="s2">"""</span>
<span class="s2"> create table person(</span>
<span class="s2"> firstname,</span>
<span class="s2"> lastname,</span>
<span class="s2"> age</span>
<span class="s2"> );</span>
<span class="s2"> create table book(</span>
<span class="s2"> title,</span>
<span class="s2"> author,</span>
<span class="s2"> published</span>
<span class="s2"> );</span>
<span class="s2"> insert into book(title, author, published)</span>
<span class="s2"> values (</span>
<span class="s2"> 'Dirk Gently''s Holistic Detective Agency',</span>
<span class="s2"> 'Douglas Adams',</span>
<span class="s2"> 1987</span>
<span class="s2"> );</span>
<span class="s2"> """</span><span class="p">)</span>
</code></pre></dd></dl><dl class="method"><dt id="sqlite3.Cursor.fetchone"><span class="yiyi-st" id="yiyi-236"> <code class="descname">fetchone</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-237">获取查询结果集的下一行,返回单一序列,如果没有数据可用,返回<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></p></dd></dl><dl class="method"><dt id="sqlite3.Cursor.fetchmany"><span class="yiyi-st" id="yiyi-238"> <code class="descname">fetchmany</code><span class="sig-paren">(</span><em>size=cursor.arraysize</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-239">获取查询结果的下一组行,返回一个列表。</span><span class="yiyi-st" id="yiyi-240">没有更多行时,将返回空的列表。</span></p><p><span class="yiyi-st" id="yiyi-241"><em>size</em>参数指定每次调用需要获取的行数。</span><span class="yiyi-st" id="yiyi-242">如果它不给,游标的 arraysize 确定要读取的行数。</span><span class="yiyi-st" id="yiyi-243">该方法设法获取尽可能多的由size参数所示数目的行。</span><span class="yiyi-st" id="yiyi-244">如果这不可行(由于指定数目的行不可用),可能会返回较少行数。</span></p><p><span class="yiyi-st" id="yiyi-245">请注意关于<em>size</em>参数有性能上的考量。</span><span class="yiyi-st" id="yiyi-246">为获得最佳性能,通常最好使用 arraysize 属性。</span><span class="yiyi-st" id="yiyi-247">如果使用<em>size</em>参数,最好每次调用<a class="reference internal" href="#sqlite3.Cursor.fetchmany" title="sqlite3.Cursor.fetchmany"><code class="xref py py-meth docutils literal"><span class="pre">fetchmany()</span></code></a>都用相同的值。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Cursor.fetchall"><span class="yiyi-st" id="yiyi-248"> <code class="descname">fetchall</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-249">获取查询结果的所有(剩余)行,返回一个列表。</span><span class="yiyi-st" id="yiyi-250">请注意游标的 arraysize 属性可以影响此操作的性能。</span><span class="yiyi-st" id="yiyi-251">没有行可用时,则返回一个空列表。</span></p></dd></dl><dl class="method"><dt id="sqlite3.Cursor.close"><span class="yiyi-st" id="yiyi-252"> <code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-253">现在关闭光标(而不是每次调用<code class="docutils literal"><span class="pre">__del__</span></code>时)。</span></p><p><span class="yiyi-st" id="yiyi-254">光标将从这一点向前不可用;如果使用光标进行任何操作,则会出现<code class="docutils literal"><span class="pre">ProgrammingError</span></code>异常。</span></p></dd></dl><dl class="attribute"><dt id="sqlite3.Cursor.rowcount"><span class="yiyi-st" id="yiyi-255"> <code class="descname">rowcount</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-256">虽然<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">sql3</span></code></a>模块的<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">curcor</span></code></a>类实现了该属性,怪异的是数据库引擎自己支持如何决定"受影响行"/"被选择行"。</span></p><p><span class="yiyi-st" id="yiyi-257">对于<a class="reference internal" href="#sqlite3.Cursor.executemany" title="sqlite3.Cursor.executemany"><code class="xref py py-meth docutils literal"><span class="pre">executemany()</span></code></a>语句,修改总数被累加到<a class="reference internal" href="#sqlite3.Cursor.rowcount" title="sqlite3.Cursor.rowcount"><code class="xref py py-attr docutils literal"><span class="pre">rowcount</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-258">根据Python DB API 规范的要求,<a class="reference internal" href="#sqlite3.Cursor.rowcount" title="sqlite3.Cursor.rowcount"><code class="xref py py-attr docutils literal"><span class="pre">rowcount</span></code></a>属性是-1 如果在游标上没有执行<code class="docutils literal"><span class="pre">executeXX()</span></code>或者接口无法判断上次操作的rowcount。</span><span class="yiyi-st" id="yiyi-259">这包括<code class="docutils literal"><span class="pre">SELECT</span></code>语句,因为我们无法确定查询所产生的行数,直到所有的行被获取为止。</span></p><p><span class="yiyi-st" id="yiyi-260">SQLite 3.6.5之前,如果无条件的<code class="docutils literal"><span class="pre">DELETE </span><span class="pre">FROM</span> <span class="pre">talbe</span></code><a class="reference internal" href="#sqlite3.Cursor.rowcount" title="sqlite3.Cursor.rowcount"><code class="xref py py-attr docutils literal"><span class="pre">rowcount</span></code></a>为 0。</span></p></dd></dl><dl class="attribute"><dt id="sqlite3.Cursor.lastrowid"><span class="yiyi-st" id="yiyi-261"> <code class="descname">lastrowid</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-262">此只读属性提供最后被修改行的 rowid 。</span><span class="yiyi-st" id="yiyi-263">仅当您使用<a class="reference internal" href="#sqlite3.Cursor.execute" title="sqlite3.Cursor.execute"><code class="xref py py-meth docutils literal"><span class="pre">execute()</span></code></a>方法发出<code class="docutils literal"><span class="pre">INSERT</span></code>语句时,才会设置此选项。</span><span class="yiyi-st" id="yiyi-264">对于非<code class="docutils literal"><span class="pre">INSERT</span></code>的其它操作或调用<a class="reference internal" href="#sqlite3.Cursor.executemany" title="sqlite3.Cursor.executemany"><code class="xref py py-meth docutils literal"><span class="pre">executemany()</span></code></a> <a class="reference internal" href="#sqlite3.Cursor.lastrowid" title="sqlite3.Cursor.lastrowid"><code class="xref py py-attr docutils literal"><span class="pre">lastrowid</span></code></a>设置为<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></p></dd></dl><dl class="attribute"><dt id="sqlite3.Cursor.description"><span class="yiyi-st" id="yiyi-265"> <code class="descname">description</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-266">此只读属性提供最后一个查询的列名称。</span><span class="yiyi-st" id="yiyi-267">为了保持与 Python DB API 兼容,它对每一个列返回一个 7 元组每个元组的后面的6个元素都是<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-268">对于没有匹配到任何一行的<code class="docutils literal"><span class="pre">SELECT</span></code>语句该属性也被设置。</span></p></dd></dl><dl class="attribute"><dt id="sqlite3.Cursor.connection"><span class="yiyi-st" id="yiyi-269"> <code class="descname">connection</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-270">此只读属性提供由<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">Cursor</span></code></a>对象使用的SQLite数据库<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a></span><span class="yiyi-st" id="yiyi-271">通过调用<a class="reference internal" href="#sqlite3.Connection.cursor" title="sqlite3.Connection.cursor"><code class="xref py py-meth docutils literal"><span class="pre">con.cursor()</span></code></a>创建的<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">Cursor</span></code></a>对象将具有指向<em>con</em><a class="reference internal" href="#sqlite3.Cursor.connection" title="sqlite3.Cursor.connection"><code class="xref py py-attr docutils literal"><span class="pre">connection</span></code></a>属性:</span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cur</span><span class="o">.</span><span class="n">connection</span> <span class="o">==</span> <span class="n">con</span>
<span class="go">True</span>
</code></pre></dd></dl></dd></dl></div><div class="section" id="row-objects"><h2><span class="yiyi-st" id="yiyi-272">12.6.4. </span><span class="yiyi-st" id="yiyi-273">Row Objects</span></h2><dl class="class"><dt id="sqlite3.Row"><span class="yiyi-st" id="yiyi-274"> <em class="property">class </em><code class="descclassname">sqlite3.</code><code class="descname">Row</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-275"><a class="reference internal" href="#sqlite3.Row" title="sqlite3.Row"><code class="xref py py-class docutils literal"><span class="pre">Row</span></code></a>实例作为<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>对象的高度优化的<a class="reference internal" href="#sqlite3.Connection.row_factory" title="sqlite3.Connection.row_factory"><code class="xref py py-attr docutils literal"><span class="pre">row_factory</span></code></a></span><span class="yiyi-st" id="yiyi-276">在大多数功能中它试图模仿一个元组。</span></p><p><span class="yiyi-st" id="yiyi-277">它支持通过列名和索引的映射访问,迭代,表现,相等性测试和<a class="reference internal" href="functions.html#len" title="len"><code class="xref py py-func docutils literal"><span class="pre">len()</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-278">如果两个<a class="reference internal" href="#sqlite3.Row" title="sqlite3.Row"><code class="xref py py-class docutils literal"><span class="pre">Row</span></code></a>对象具有完全相同的列且它们的成员都是相等,则他们比较结果相等。</span></p><dl class="method"><dt id="sqlite3.Row.keys"><span class="yiyi-st" id="yiyi-279"> <code class="descname">keys</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-280">此方法返回列名称的列表。</span><span class="yiyi-st" id="yiyi-281">在查询后,它是在<a class="reference internal" href="#sqlite3.Cursor.description" title="sqlite3.Cursor.description"><code class="xref py py-attr docutils literal"><span class="pre">Cursor.description</span></code></a>中每个元组的第一个成员。</span></p></dd></dl><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-282"><span class="versionmodified">在版本3.5中已更改:</span>添加了切片支持。</span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-283">假定初始化一个前述例子中的表:</span></p><pre><code class="language-python"><span></span><span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'''create table stocks</span>
<span class="s1">(date text, trans text, symbol text,</span>
<span class="s1"> qty real, price real)'''</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""insert into stocks</span>
<span class="s2"> values ('2006-01-05','BUY','RHAT',100,35.14)"""</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
<span class="n">c</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-284">现在我们插入<a class="reference internal" href="#sqlite3.Row" title="sqlite3.Row"><code class="xref py py-class docutils literal"><span class="pre">Row</span></code></a></span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">conn</span><span class="o">.</span><span class="n">row_factory</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Row</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'select * from stocks'</span><span class="p">)</span>
<span class="go">&lt;sqlite3.Cursor object at 0x7f4e7dd8fa80&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="go">&lt;class 'sqlite3.Row'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">tuple</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="go">('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="go">5</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="go">'RHAT'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
<span class="go">['date', 'trans', 'symbol', 'qty', 'price']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="s1">'qty'</span><span class="p">]</span>
<span class="go">100.0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">member</span> <span class="ow">in</span> <span class="n">r</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">member</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">2006-01-05</span>
<span class="go">BUY</span>
<span class="go">RHAT</span>
<span class="go">100.0</span>
<span class="go">35.14</span>
</code></pre></div><div class="section" id="sqlite-and-python-types"><h2><span class="yiyi-st" id="yiyi-285">12.6.5. </span><span class="yiyi-st" id="yiyi-286">SQLite and Python types</span></h2><div class="section" id="introduction"><h3><span class="yiyi-st" id="yiyi-287">12.6.5.1. </span><span class="yiyi-st" id="yiyi-288">Introduction</span></h3><p><span class="yiyi-st" id="yiyi-289">SQLite 天然支持以下类型:<code class="docutils literal"><span class="pre">NULL</span></code><code class="docutils literal"><span class="pre">INTEGER</span></code><code class="docutils literal"><span class="pre">REAL</span></code><code class="docutils literal"><span class="pre">TEXT</span></code><code class="docutils literal"><span class="pre">BLOB</span></code></span></p><p><span class="yiyi-st" id="yiyi-290">因此下述Python类型可以没有任何问题地直接发送给SQLite。</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-291">Python类型</span></th><th class="head"><span class="yiyi-st" id="yiyi-292">SQLite类型</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-293"><a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-294"><code class="docutils literal"><span class="pre">NULL</span></code></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-295"><a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-class docutils literal"><span class="pre">int</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-296"><code class="docutils literal"><span class="pre">INTEGER</span></code></span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-297"><a class="reference internal" href="functions.html#float" title="float"><code class="xref py py-class docutils literal"><span class="pre">float</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-298"><code class="docutils literal"><span class="pre">REAL</span></code></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-299"><a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-300"><code class="docutils literal"><span class="pre">TEXT</span></code></span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-301"><a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-302"><code class="docutils literal"><span class="pre">BLOB</span></code></span></td></tr></tbody></table><p><span class="yiyi-st" id="yiyi-303">默认情况下SQLite类型将这样转换成Python类型</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-304">SQLite类型</span></th><th class="head"><span class="yiyi-st" id="yiyi-305">Python类型</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-306"><code class="docutils literal"><span class="pre">NULL</span></code></span></td><td><span class="yiyi-st" id="yiyi-307"><a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-308"><code class="docutils literal"><span class="pre">INTEGER</span></code></span></td><td><span class="yiyi-st" id="yiyi-309"><a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-class docutils literal"><span class="pre">int</span></code></a></span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-310"><code class="docutils literal"><span class="pre">REAL</span></code></span></td><td><span class="yiyi-st" id="yiyi-311"><a class="reference internal" href="functions.html#float" title="float"><code class="xref py py-class docutils literal"><span class="pre">float</span></code></a></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-312"><code class="docutils literal"><span class="pre">TEXT</span></code></span></td><td><span class="yiyi-st" id="yiyi-313">默认情况下取决于<a class="reference internal" href="#sqlite3.Connection.text_factory" title="sqlite3.Connection.text_factory"><code class="xref py py-attr docutils literal"><span class="pre">text_factory</span></code></a><a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a></span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-314"><code class="docutils literal"><span class="pre">BLOB</span></code></span></td><td><span class="yiyi-st" id="yiyi-315"><a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a></span></td></tr></tbody></table><p><span class="yiyi-st" id="yiyi-316"><a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块的类型系统可以以两种方式来扩展通过对象适配可以在SQLite数据库中存储其它的Python类型通过转换器让<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块将SQLite类型转成不同的Python类型。</span></p></div><div class="section" id="using-adapters-to-store-additional-python-types-in-sqlite-databases"><h3><span class="yiyi-st" id="yiyi-317">12.6.5.2. </span><span class="yiyi-st" id="yiyi-318">Using adapters to store additional Python types in SQLite databases</span></h3><p><span class="yiyi-st" id="yiyi-319">如之前所述SQLite 天然只支持有限的类型。</span><span class="yiyi-st" id="yiyi-320">要使用其他Python类型与SQLite您必须<strong>适应</strong>它们为sqlite3模块支持的SQLite类型之一NoneTypeintfloatstrbytes。</span></p><p><span class="yiyi-st" id="yiyi-321">有两种方法,可以使<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块适配一个Python类型到一个支持的类型。</span></p><div class="section" id="letting-your-object-adapt-itself"><h4><span class="yiyi-st" id="yiyi-322">12.6.5.2.1. </span><span class="yiyi-st" id="yiyi-323">Letting your object adapt itself</span></h4><p><span class="yiyi-st" id="yiyi-324">这是一种好方法,如果您自己编写类。</span><span class="yiyi-st" id="yiyi-325">让我们假设您有一个像这样的类:</span></p><pre><code class="language-python"><span></span><span class="k">class</span> <span class="nc">Point</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
</code></pre><p><span class="yiyi-st" id="yiyi-326">想要在单一的 SQLite 列中存储点。</span><span class="yiyi-st" id="yiyi-327">首先得选一个支持的类型,它可以用来表示点。</span><span class="yiyi-st" id="yiyi-328">假定使用 str ,并用分号来分隔坐标。</span><span class="yiyi-st" id="yiyi-329">需要给类加一个<code class="docutils literal"><span class="pre">__conform__(self, </span> <span class="pre">protocl)</span> </code> ,该方法必须返回转换后的值。</span><span class="yiyi-st" id="yiyi-330">参数<em>protocol</em><code class="xref py py-class docutils literal"><span class="pre">PrepareProtocol</span></code></span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">class</span> <span class="nc">Point</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">__conform__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">protocol</span><span class="p">):</span>
<span class="k">if</span> <span class="n">protocol</span> <span class="ow">is</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">PrepareProtocol</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">"</span><span class="si">%f</span><span class="s2">;</span><span class="si">%f</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="mf">4.0</span><span class="p">,</span> <span class="o">-</span><span class="mf">3.2</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select ?"</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">,))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
</code></pre></div><div class="section" id="registering-an-adapter-callable"><h4><span class="yiyi-st" id="yiyi-331">12.6.5.2.2. </span><span class="yiyi-st" id="yiyi-332">Registering an adapter callable</span></h4><p><span class="yiyi-st" id="yiyi-333">另一种可能性就是创建一个函数,它用来将类型转成字符串表现形式,然后用<a class="reference internal" href="#sqlite3.register_adapter" title="sqlite3.register_adapter"><code class="xref py py-meth docutils literal"><span class="pre">register_adapter()</span></code></a>来注册该函数。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">class</span> <span class="nc">Point</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">adapt_point</span><span class="p">(</span><span class="n">point</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">"</span><span class="si">%f</span><span class="s2">;</span><span class="si">%f</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">point</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">point</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
<span class="n">sqlite3</span><span class="o">.</span><span class="n">register_adapter</span><span class="p">(</span><span class="n">Point</span><span class="p">,</span> <span class="n">adapt_point</span><span class="p">)</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="mf">4.0</span><span class="p">,</span> <span class="o">-</span><span class="mf">3.2</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select ?"</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">,))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
</code></pre><p><span class="yiyi-st" id="yiyi-334"><a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块为 Python 的内置<a class="reference internal" href="datetime.html#datetime.date" title="datetime.date"><code class="xref py py-class docutils literal"><span class="pre">datetime.date</span></code></a><a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a>类型有两个默认适配器。</span><span class="yiyi-st" id="yiyi-335">假定想要将<a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a>对象不以ISO形式存储而是存成Unix 时间戳。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="k">def</span> <span class="nf">adapt_datetime</span><span class="p">(</span><span class="n">ts</span><span class="p">):</span>
<span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="n">ts</span><span class="o">.</span><span class="n">timetuple</span><span class="p">())</span>
<span class="n">sqlite3</span><span class="o">.</span><span class="n">register_adapter</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">,</span> <span class="n">adapt_datetime</span><span class="p">)</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select ?"</span><span class="p">,</span> <span class="p">(</span><span class="n">now</span><span class="p">,))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
</code></pre></div></div><div class="section" id="converting-sqlite-values-to-custom-python-types"><h3><span class="yiyi-st" id="yiyi-336">12.6.5.3. </span><span class="yiyi-st" id="yiyi-337">Converting SQLite values to custom Python types</span></h3><p><span class="yiyi-st" id="yiyi-338">编写适配器允许将自定义Python类型转成SQLite类型。</span><span class="yiyi-st" id="yiyi-339">但是要真的有用我们必须也提供SQLite类型转成Python类型。</span></p><p><span class="yiyi-st" id="yiyi-340">进入转换器。</span></p><p><span class="yiyi-st" id="yiyi-341">让我们回到<code class="xref py py-class docutils literal"><span class="pre">Point</span></code>类。</span><span class="yiyi-st" id="yiyi-342">在SQLite中以字符串的形式存储分号分隔的x、y坐标。</span></p><p><span class="yiyi-st" id="yiyi-343">首先定义一个转换器函数,它接收字符串参数,并从中构造一个<code class="xref py py-class docutils literal"><span class="pre">Point</span></code>对象。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-344"></span></p><p class="last"><span class="yiyi-st" id="yiyi-345">转换器函数<strong>总是</strong>使用<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象调用无论将数据类型发送到SQLite的哪种数据类型。</span></p></div><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">convert_point</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">b</span><span class="s2">";"</span><span class="p">))</span>
<span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-346">先在需要让<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块知道你从数据库中选择的实际上是个点。</span><span class="yiyi-st" id="yiyi-347">有两种方法做这件事:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-348">Implicitly via the declared type隐式地通过声明的类型</span></li><li><span class="yiyi-st" id="yiyi-349">Explicitly via the column name 明确地通过列名</span></li></ul><p><span class="yiyi-st" id="yiyi-350">这两种方法在<a class="reference internal" href="#sqlite3-module-contents"><span>Module functions and constants</span></a>章节中都有描述,具体在<a class="reference internal" href="#sqlite3.PARSE_DECLTYPES" title="sqlite3.PARSE_DECLTYPES"><code class="xref py py-const docutils literal"><span class="pre">PARSE_DECLTYPES</span></code></a><a class="reference internal" href="#sqlite3.PARSE_COLNAMES" title="sqlite3.PARSE_COLNAMES"><code class="xref py py-const docutils literal"><span class="pre">PARSE_COLNAMES</span></code></a>中。</span></p><p><span class="yiyi-st" id="yiyi-351">下面的示例阐释了这两种方法。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="k">class</span> <span class="nc">Point</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">"(</span><span class="si">%f</span><span class="s2">;</span><span class="si">%f</span><span class="s2">)"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">adapt_point</span><span class="p">(</span><span class="n">point</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s2">"</span><span class="si">%f</span><span class="s2">;</span><span class="si">%f</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">point</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">point</span><span class="o">.</span><span class="n">y</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">convert_point</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">b</span><span class="s2">";"</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="c1"># Register the adapter</span>
<span class="n">sqlite3</span><span class="o">.</span><span class="n">register_adapter</span><span class="p">(</span><span class="n">Point</span><span class="p">,</span> <span class="n">adapt_point</span><span class="p">)</span>
<span class="c1"># Register the converter</span>
<span class="n">sqlite3</span><span class="o">.</span><span class="n">register_converter</span><span class="p">(</span><span class="s2">"point"</span><span class="p">,</span> <span class="n">convert_point</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="mf">4.0</span><span class="p">,</span> <span class="o">-</span><span class="mf">3.2</span><span class="p">)</span>
<span class="c1">#########################</span>
<span class="c1"># 1) Using declared types</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">,</span> <span class="n">detect_types</span><span class="o">=</span><span class="n">sqlite3</span><span class="o">.</span><span class="n">PARSE_DECLTYPES</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table test(p point)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into test(p) values (?)"</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">,))</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select p from test"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"with declared types:"</span><span class="p">,</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">cur</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">con</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1">#######################</span>
<span class="c1"># 1) Using column names</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">,</span> <span class="n">detect_types</span><span class="o">=</span><span class="n">sqlite3</span><span class="o">.</span><span class="n">PARSE_COLNAMES</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table test(p)"</span><span class="p">)</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into test(p) values (?)"</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">,))</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'select p as "p [point]" from test'</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"with column names:"</span><span class="p">,</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">cur</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">con</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div><div class="section" id="default-adapters-and-converters"><h3><span class="yiyi-st" id="yiyi-352">12.6.5.4. </span><span class="yiyi-st" id="yiyi-353">Default adapters and converters</span></h3><p><span class="yiyi-st" id="yiyi-354">在datetime模块中有对date和datetime类型的默认的适配器。</span><span class="yiyi-st" id="yiyi-355">它们将ISO datesISO timestamps发送给SQLite。</span></p><p><span class="yiyi-st" id="yiyi-356">默认的转换器以"date"为名注册给<a class="reference internal" href="datetime.html#datetime.date" title="datetime.date"><code class="xref py py-class docutils literal"><span class="pre">datetime.date</span></code></a>,以"timestamp"为名注册给<a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-357">这样在大多数情况下可以在Python中使用datetimestamp而不需要额外的动作。</span><span class="yiyi-st" id="yiyi-358">适配器的格式兼容于SQLite实际上的date/time函数。</span></p><p><span class="yiyi-st" id="yiyi-359">下面的示例演示这点。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">,</span> <span class="n">detect_types</span><span class="o">=</span><span class="n">sqlite3</span><span class="o">.</span><span class="n">PARSE_DECLTYPES</span><span class="o">|</span><span class="n">sqlite3</span><span class="o">.</span><span class="n">PARSE_COLNAMES</span><span class="p">)</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table test(d date, ts timestamp)"</span><span class="p">)</span>
<span class="n">today</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into test(d, ts) values (?, ?)"</span><span class="p">,</span> <span class="p">(</span><span class="n">today</span><span class="p">,</span> <span class="n">now</span><span class="p">))</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select d, ts from test"</span><span class="p">)</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">today</span><span class="p">,</span> <span class="s2">"=&gt;"</span><span class="p">,</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">type</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">now</span><span class="p">,</span> <span class="s2">"=&gt;"</span><span class="p">,</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nb">type</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'select current_date as "d [date]", current_timestamp as "ts [timestamp]"'</span><span class="p">)</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">cur</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"current_date"</span><span class="p">,</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">type</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"current_timestamp"</span><span class="p">,</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nb">type</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
</code></pre><p><span class="yiyi-st" id="yiyi-360">如果存储在SQLite中的时间戳的小数部分大于6个数字它的值将由时间戳转换器截断至微秒的精度。</span></p></div></div><div class="section" id="controlling-transactions"><h2><span class="yiyi-st" id="yiyi-361">12.6.6. </span><span class="yiyi-st" id="yiyi-362">Controlling Transactions</span></h2><p><span class="yiyi-st" id="yiyi-363">默认情况下,<a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块在数据修改语言DML语句之前隐式打开事务。</span><span class="yiyi-st" id="yiyi-364"><code class="docutils literal"><span class="pre">(DML:INSERT</span></code> / <code class="docutils literal"><span class="pre">UPDATE</span></code> / <code class="docutils literal"><span class="pre">DELETE</span></code> / <code class="docutils literal"><span class="pre">REPLACE</span></code>)(即除<code class="docutils literal"><span class="pre">SELECT</span></code>之外的任何东西或上述内容)。</span></p><p><span class="yiyi-st" id="yiyi-365">所以如果在事务中发出<code class="docutils literal"><span class="pre">CREATE</span> <span class="pre">TABLE</span> <span class="pre">...</span></code><code class="docutils literal"><span class="pre">VACUUM</span></code><code class="docutils literal"><span class="pre">PRAGMA</span></code>这样的命令, <a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块将在执行这些命令之前隐式提交事务。</span><span class="yiyi-st" id="yiyi-366">这样做有两个理由。</span><span class="yiyi-st" id="yiyi-367">首先这些命令在事务中不起作用。</span><span class="yiyi-st" id="yiyi-368">另一个原因就是sqlite3需要跟踪事务状态激活还是非激活</span><span class="yiyi-st" id="yiyi-369">当前事务状态通过连接对象的<a class="reference internal" href="#sqlite3.Connection.in_transaction" title="sqlite3.Connection.in_transaction"><code class="xref py py-attr docutils literal"><span class="pre">Connection.in_transaction</span></code></a>属性显示。</span></p><p><span class="yiyi-st" id="yiyi-370">通过<a class="reference internal" href="#sqlite3.connect" title="sqlite3.connect"><code class="xref py py-func docutils literal"><span class="pre">connect()</span></code></a>调用的<em>isolation_level</em>参数或者连接的<code class="xref py py-attr docutils literal"><span class="pre">isolation_level</span></code>属性可以控制sqlite3隐式的执行哪种<code class="docutils literal"><span class="pre">BEGIN</span></code>语句(或者完全不执行)。</span></p><p><span class="yiyi-st" id="yiyi-371">如果需要<strong>自动提交模式autocommint mode</strong>,将<code class="xref py py-attr docutils literal"><span class="pre">isolation_level</span></code>设置为None。</span></p><p><span class="yiyi-st" id="yiyi-372">其他情况下,保留其默认值,这将产生一个简单的"BEGIN"语句或者将其设置成SQLite支持的隔离级别“DEFERRED”、“IMMEDIATE”、或者“EXCLUSIVE”。</span></p></div><div class="section" id="using-sqlite3-efficiently"><h2><span class="yiyi-st" id="yiyi-373">12.6.7. </span><span class="yiyi-st" id="yiyi-374">Using <a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a> efficiently</span></h2><div class="section" id="using-shortcut-methods"><h3><span class="yiyi-st" id="yiyi-375">12.6.7.1. </span><span class="yiyi-st" id="yiyi-376">Using shortcut methods</span></h3><p><span class="yiyi-st" id="yiyi-377">使用<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>对象的非标准的<code class="xref py py-meth docutils literal"><span class="pre">executescript()</span></code><code class="xref py py-meth docutils literal"><span class="pre">execute()</span></code><code class="xref py py-meth docutils literal"><span class="pre">executemany()</span></code>方法,代码会更简洁,因为不用显式的创建<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">Cursor</span></code></a>对象(一般不必要)。</span><span class="yiyi-st" id="yiyi-378">这些快捷方法会隐式创建并返回<a class="reference internal" href="#sqlite3.Cursor" title="sqlite3.Cursor"><code class="xref py py-class docutils literal"><span class="pre">Cursor</span></code></a>对象。</span><span class="yiyi-st" id="yiyi-379">这样,可以直接在<a class="reference internal" href="#sqlite3.Connection" title="sqlite3.Connection"><code class="xref py py-class docutils literal"><span class="pre">Connection</span></code></a>对象上只通过一个调用就可以执行<code class="docutils literal"><span class="pre">SELECT</span></code>语句并遍历结果。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">persons</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">(</span><span class="s2">"Hugo"</span><span class="p">,</span> <span class="s2">"Boss"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"Calvin"</span><span class="p">,</span> <span class="s2">"Klein"</span><span class="p">)</span>
<span class="p">]</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="c1"># Create the table</span>
<span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table person(firstname, lastname)"</span><span class="p">)</span>
<span class="c1"># Fill the table</span>
<span class="n">con</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="s2">"insert into person(firstname, lastname) values (?, ?)"</span><span class="p">,</span> <span class="n">persons</span><span class="p">)</span>
<span class="c1"># Print the table contents</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select firstname, lastname from person"</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"I just deleted"</span><span class="p">,</span> <span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"delete from person"</span><span class="p">)</span><span class="o">.</span><span class="n">rowcount</span><span class="p">,</span> <span class="s2">"rows"</span><span class="p">)</span>
</code></pre></div><div class="section" id="accessing-columns-by-name-instead-of-by-index"><h3><span class="yiyi-st" id="yiyi-380">12.6.7.2. </span><span class="yiyi-st" id="yiyi-381">Accessing columns by name instead of by index</span></h3><p><span class="yiyi-st" id="yiyi-382"><a class="reference internal" href="#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a>模块的一个有用功能是内部<a class="reference internal" href="#sqlite3.Row" title="sqlite3.Row"><code class="xref py py-class docutils literal"><span class="pre">sqlite3.Row</span></code></a>类,设计用作行工厂。</span></p><p><span class="yiyi-st" id="yiyi-383">由此类包装过的行可以按索引来访问(像元组),也可以按大小写无关的名字来访问。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">row_factory</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Row</span>
<span class="n">cur</span> <span class="o">=</span> <span class="n">con</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
<span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select 'John' as name, 42 as age"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">cur</span><span class="p">:</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">row</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">==</span> <span class="n">row</span><span class="p">[</span><span class="s2">"nAmE"</span><span class="p">]</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">row</span><span class="p">[</span><span class="s2">"age"</span><span class="p">]</span>
<span class="k">assert</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">row</span><span class="p">[</span><span class="s2">"AgE"</span><span class="p">]</span>
</code></pre></div><div class="section" id="using-the-connection-as-a-context-manager"><h3><span class="yiyi-st" id="yiyi-384">12.6.7.3. </span><span class="yiyi-st" id="yiyi-385">Using the connection as a context manager</span></h3><p><span class="yiyi-st" id="yiyi-386">连接对象可以用作上下文管理器来自动提交或回滚事务。</span><span class="yiyi-st" id="yiyi-387">在异常的情况下,事务被回滚;否则,事务被提交:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">sqlite3</span>
<span class="n">con</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">)</span>
<span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"create table person (id integer primary key, firstname varchar unique)"</span><span class="p">)</span>
<span class="c1"># Successful, con.commit() is called automatically afterwards</span>
<span class="k">with</span> <span class="n">con</span><span class="p">:</span>
<span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into person(firstname) values (?)"</span><span class="p">,</span> <span class="p">(</span><span class="s2">"Joe"</span><span class="p">,))</span>
<span class="c1"># con.rollback() is called after the with block finishes with an exception, the</span>
<span class="c1"># exception is still raised and must be caught</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">with</span> <span class="n">con</span><span class="p">:</span>
<span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"insert into person(firstname) values (?)"</span><span class="p">,</span> <span class="p">(</span><span class="s2">"Joe"</span><span class="p">,))</span>
<span class="k">except</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">IntegrityError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"couldn't add Joe twice"</span><span class="p">)</span>
</code></pre></div></div><div class="section" id="common-issues"><h2><span class="yiyi-st" id="yiyi-388">12.6.8. </span><span class="yiyi-st" id="yiyi-389">Common issues</span></h2><div class="section" id="multithreading"><h3><span class="yiyi-st" id="yiyi-390">12.6.8.1. </span><span class="yiyi-st" id="yiyi-391">Multithreading</span></h3><p><span class="yiyi-st" id="yiyi-392">老版SQLite线程间共享连接时有问题。</span><span class="yiyi-st" id="yiyi-393">这就是为什么 Python 模块不允许线程间共享连接和游标。</span><span class="yiyi-st" id="yiyi-394">如果你仍然试图这样做,则会在运行时异常。</span></p><p><span class="yiyi-st" id="yiyi-395">唯一的例外就是调用<a class="reference internal" href="#sqlite3.Connection.interrupt" title="sqlite3.Connection.interrupt"><code class="xref py py-meth docutils literal"><span class="pre">interrupt()</span></code></a>方法,它只在从不同线程中调用时有意义。</span></p><p class="rubric"><span class="yiyi-st" id="yiyi-396">脚注</span></p><table class="docutils footnote" frame="void" id="f1" rules="none"><tbody valign="top"><tr><td class="label"><span class="yiyi-st" id="yiyi-397">[1]</span></td><td><span class="yiyi-st" id="yiyi-398"><em><a class="fn-backref" href="#id1">1</a><a class="fn-backref" href="#id2">2</a></em>默认情况下sqlite3模块不支持可加载扩展因为一些平台特别是Mac OS X没有此功能的库。</span><span class="yiyi-st" id="yiyi-399">要获得可加载的扩展支持,必须传递-enable-loadable-sqlite-extensions以进行配置。</span></td></tr></tbody></table></div></div></div></div>