1
0
wiki/Technology/ProgrammingLanguage/Python/进阶/数据库操作.html

683 lines
547 KiB
HTML
Raw Normal View History

2024-09-03 21:23:28 +08:00
<!DOCTYPE html>
<html><head><title>数据库操作</title><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta property="og:title" content="数据库操作"/><meta property="og:description" content="Python DB-API 2.0 规范是一个重要的标准,它为 Python 程序与数据库间的交互提供了一致的接口。这个规范的目标是简化数据库编程,同时保持足够的灵活性来支持不同的数据库系统。."/><meta property="og:image" content="https://wiki.7wate.com/static/og-image.png"/><meta property="og:width" content="1200"/><meta property="og:height" content="675"/><link rel="icon" href="../../../../static/icon.png"/><meta name="description" content="Python DB-API 2.0 规范是一个重要的标准,它为 Python 程序与数据库间的交互提供了一致的接口。这个规范的目标是简化数据库编程,同时保持足够的灵活性来支持不同的数据库系统。."/><meta name="generator" content="Quartz"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com"/><script async src="https://umami.7wate.com/script.js" data-website-id="c061efdc-95dd-4d21-9d04-a1ffda0a85b9"></script><script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?94d8ccb156eb7c65abf317e6e01cdba9";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script><script async src="https://www.googletagmanager.com/gtag/js?id=G-MHMEL0F832"></script><script>
(function() {
window.dataLayer = window.dataLayer || [];
function gtag() {
window.dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-MHMEL0F832');
})();
</script><link href="../../../../index.css" rel="stylesheet" type="text/css" spa-preserve/><link href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" rel="stylesheet" type="text/css" spa-preserve/><link href="https://fonts.googleapis.com/css2?family=IBM Plex Mono&amp;family=Schibsted Grotesk:wght@400;700&amp;family=Source Sans Pro:ital,wght@0,400;0,600;1,400;1,600&amp;display=swap" rel="stylesheet" type="text/css" spa-preserve/><script src="../../../../prescript.js" type="application/javascript" spa-preserve></script><script type="application/javascript" spa-preserve>const fetchData = fetch(`../../../../static/contentIndex.json`).then(data => data.json())</script></head><body data-slug="Technology/ProgrammingLanguage/Python/进阶/数据库操作"><div id="quartz-root" class="page"><div id="quartz-body"><div class="left sidebar"><h1 class="page-title "><a href="../../../..">📚 X·Eden</a></h1><div class="spacer mobile-only"></div><div class="search "><div id="search-icon"><p>Search</p><div></div><svg tabIndex="0" aria-labelledby="title desc" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.9 19.7"><title id="title">Search</title><desc id="desc">Search</desc><g class="search-path" fill="none"><path stroke-linecap="square" d="M18.5 18.3l-5.4-5.4"></path><circle cx="8" cy="8" r="7"></circle></g></svg></div><div id="search-container"><div id="search-space"><input autocomplete="off" id="search-bar" name="search" type="text" aria-label="Search for something" placeholder="Search for something"/><div id="results-container"></div></div></div></div><div class="darkmode "><input class="toggle" id="darkmode-toggle" type="checkbox" tabIndex="-1"/><label id="toggle-label-light" for="darkmode-toggle" tabIndex="-1"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1" id="dayIcon" x="0px" y="0px" viewBox="0 0 35 35" style="enable-background:new 0 0 35 35;" xmlSpace="preserve"><title>Light mode</title><path d="M6,17.5C6,16.672,5.328,16,4.5,16h-3C0.672,16,0,16.672,0,17.5 S0.672,19,1.5,19h3C5.328,19,6,18.328,6,17.5z M7.5,26c-0.414,0-0.789,0.168-1.061,0.439l-2,2C4.168,28.711,4,29.086,4,29.5 C4,30.328,4.671,31,5.5,31c0.414,0,0.789-0.168,1.06-0.44l2-2C8.832,28.289,9,27.914,9,27.5C9,26.672,8.329,26,7.5,26z M17.5,6 C18.329,6,19,5.328,19,4.5v-3C19,0.672,18.329,0,17.5,0S16,0.672,16,1.5v3C16,5.328,16.671,6,17.5,6z M27.5,9 c0.414,0,0.789-0.168,1.06-0.439l2-2C30.832,6.289,31,5.914,31,5.5C31,4.672,30.329,4,29.5,4c-0.414,0-0.789,0.168-1.061,0.44 l-2,2C26.168,6.711,26,7.086,26,7.5C26,8.328,26.671,9,27.5,9z M6.439,8.561C6.711,8.832,7.086,9,7.5,9C8.328,9,9,8.328,9,7.5 c0-0.414-0.168-0.789-0.439-1.061l-2-2C6.289,4.168,5.914,4,5.5,4C4.672,4,4,4.672,4,5.5c0,0.414,0.168,0.789,0.439,1.06 L6.439,8.561z M33.5,16h-3c-0.828,0-1.5,0.672-1.5,1.5s0.672,1.5,1.5,1.5h3c0.828,0,1.5-0.672,1.5-1.5S34.328,16,33.5,16z M28.561,26.439C28.289,26.168,27.914,26,27.5,26c-0.828,0-1.5,0.672-1.5,1.5c0,0.414,0.168,0.789,0.439,1.06l2,2 C28.711,30.832,29.086,31,29.5,31c0.828,0,1.5-0.672,1.5-1.5c0-0.414-0.168-0.789-0.439-1.061L28.561,26.439z M17.5,29 c-0.829,0-1.5,0.672-1.5,1.5v3c0,0.828,0.671,1.5,1.5,1.5s1.5-0.672,1.5-1.5v-3C19,29.672,18.329,29,17.5,29z M17.5,7 C11.71,7,7,11.71,7,17.5S11.71,28,17.5,28S28,23.29,28,17.5S23.29,7,17.5,7z M17.5,25c-4.136,0-7.5-3.364-7.5-7.5 c0-4.136,3.364-7.5,7.5-7.5c4.136,0,7.5,3.364,7.5,7.5C25,21.636,21.636,25,17.5,25z"></path></svg></label><label id="toggle-label-dark" for="darkmode-toggle" tabIndex="-1"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1" id="nightIcon" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background='new 0 0 100 100'" xmlSpace="preserve"><title>Dark mode</title><path d="M96.76,66.458c-0.853-0.852-2.15-1.064-3.23-0.534c-6.063,2.991-12.858,4.571-19.655,4.571 C62.022,70.495,50.88,65.88,42.5,57.5C29.043,44.043,25.658,23.536,34.076,6.47c0.532-1.08,0.318-2.379-0.534-3.23 c-0.851-0.852-2.15-1.064-3.23-0.534c-4.918,2.427-9.375,5.619-13.246,9.491c-9.447,9.447-14.65,22.0
<p>**Python DB-API 2.0 规范是一个重要的标准,它为 Python 程序与数据库间的交互提供了一致的接口。**这个规范的目标是简化数据库编程,同时保持足够的灵活性来支持不同的数据库系统。</p>
<p>DB-API 2.0 规范定义在 Python 标准库的 <a href="https://peps.python.org/pep-0249/" class="external">PEP 249</a> 文档中。它规定了数据库驱动(或数据库模块)应遵循的接口标准,以便程序员可以使用一致的编程风格来访问不同的数据库系统。</p>
<h3 id="核心组件">核心组件<a aria-hidden="true" tabindex="-1" href="#核心组件" class="internal"> §</a></h3>
<table><thead><tr><th>组件</th><th>描述</th><th>关键方法或属性</th></tr></thead><tbody><tr><td><strong>连接对象Connection</strong></td><td>代表数据库的连接。</td><td>- <code>connect()</code>: 连接数据库。<br/>- <code>commit()</code>: 提交当前事务。<br/>- <code>rollback()</code>: 回滚当前事务。<br/>- <code>close()</code>: 关闭连接。</td></tr><tr><td><strong>游标对象Cursor</strong></td><td>用于执行查询和获取结果。</td><td>- <code>execute(sql, [parameters])</code>: 执行 SQL 语句。<br/>- <code>executemany(sql, seq_of_parameters)</code>: 执行相同的 SQL 语句多次。<br/>- <code>fetchone()</code>: 获取结果集的下一行。<br/>- <code>fetchmany(size)</code>: 获取结果集的下几行。<br/>- <code>fetchall()</code>: 获取结果集中的所有行。<br/>- <code>close()</code>: 关闭游标对象。</td></tr></tbody></table>
<h3 id="标准方法">标准方法<a aria-hidden="true" tabindex="-1" href="#标准方法" class="internal"> §</a></h3>
<table><thead><tr><th>方法类型</th><th>方法名</th><th>描述</th></tr></thead><tbody><tr><td><strong>连接方法</strong></td><td><code>connect()</code></td><td>连接到数据库。</td></tr><tr><td></td><td><code>commit()</code></td><td>提交当前的事务。</td></tr><tr><td></td><td><code>rollback()</code></td><td>回滚当前的事务。</td></tr><tr><td></td><td><code>close()</code></td><td>关闭数据库连接。</td></tr><tr><td><strong>游标方法</strong></td><td><code>execute(sql, [parameters])</code></td><td>执行一个 SQL 语句。</td></tr><tr><td></td><td><code>executemany(sql, seq_of_parameters)</code></td><td>执行相同的 SQL 语句多次。</td></tr><tr><td></td><td><code>fetchone()</code></td><td>从结果集中获取下一行。</td></tr><tr><td></td><td><code>fetchmany(size)</code></td><td>从结果集中获取多行。</td></tr><tr><td></td><td><code>fetchall()</code></td><td>获取结果集中的所有行。</td></tr><tr><td></td><td><code>close()</code></td><td>关闭游标对象。</td></tr></tbody></table>
<h3 id="标准异常">标准异常<a aria-hidden="true" tabindex="-1" href="#标准异常" class="internal"> §</a></h3>
<table><thead><tr><th>异常类别</th><th>描述</th></tr></thead><tbody><tr><td><code>Warning</code></td><td>警告类的基类,用于非致命性问题的提示。</td></tr><tr><td><code>Error</code></td><td>与数据库相关错误的基类。如果未指定具体的异常,则抛出这个错误。</td></tr><tr><td><code>InterfaceError</code></td><td>与数据库接口(而非数据库本身)相关的错误。</td></tr><tr><td><code>DatabaseError</code></td><td>数据库操作过程中发生的错误的基类。</td></tr><tr><td><code>DataError</code></td><td>数据异常,比如数值溢出、数据类型不匹配等。</td></tr><tr><td><code>OperationalError</code></td><td>数据库操作中的内部错误,如连接问题、内存分配问题等。</td></tr><tr><td><code>IntegrityError</code></td><td>数据完整性相关的错误,如外键违反等。</td></tr><tr><td><code>InternalError</code></td><td>数据库内部错误,如游标无效、事务同步失效等。</td></tr><tr><td><code>ProgrammingError</code></td><td>程序错误如表找不到、SQL 语句语法错误等。</td></tr><tr><td><code>NotSupportedError</code></td><td>当尝试使用数据库不支持的功能或 API 时抛出的错误。</td></tr></tbody></table>
<h2 id="python-数据库操作">Python 数据库操作<a aria-hidden="true" tabindex="-1" href="#python-数据库操作" class="internal"> §</a></h2>
<p>首先,需要安装对应数据库的 Python 库,例如,如果是使用 MySQL可以安装 <code>mysql-connector-python</code>。然后,可以使用如下代码连接到数据库并执行简单的 SQL 语句:</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> sqlite3</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 连接到 SQLite 数据库</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 如果文件不存在,会自动创建</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> sqlite3</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">connect</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'example.db'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建一个游标对象,用于执行 SQL 命令</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cursor </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建一个新表</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># IF NOT EXISTS 用于避免在表已存在时产生错误</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'''</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> CREATE TABLE IF NOT EXISTS stocks</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> (date text, trans text, symbol text, qty real, price real)</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> '''</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 插入一条记录</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;INSERT INTO stocks VALUES ('2023-11-17','BUY','AAPL',100,35.14)&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 提交当前事务</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 查询数据</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM stocks WHERE symbol = 'AAPL'&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(cursor.</span><span style="color:var(--shiki-token-function);">fetchall</span><span style="color:var(--shiki-token-punctuation);">())</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 捕获任何可能发生的异常</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> sqlite3</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">Error </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;数据库错误: </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">e</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">Exception</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;非数据库错误: </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">e</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">finally</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 关闭游标</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 关闭数据库连接</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span></code></pre></div>
<h3 id="连接connection">连接Connection<a aria-hidden="true" tabindex="-1" href="#连接connection" class="internal"> §</a></h3>
<p>连接对象代表了 Python 应用程序和数据库之间的连接。通过这个连接,程序能够执行 SQL 命令、处理事务。</p>
<h4 id="创建连接">创建连接<a aria-hidden="true" tabindex="-1" href="#创建连接" class="internal"> §</a></h4>
<ul>
<li>连接是通过调用特定数据库模块的 <code>connect()</code> 函数创建的。</li>
<li>这个函数通常需要数据库特定的参数,如主机名、数据库名、用户名和密码。</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> sqlite3</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 创建连接到 SQLite 数据库文件 'example.db'</span></span>
<span data-line><span style="color:var(--shiki-color-text);">conn </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> sqlite3</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">connect</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'example.db'</span><span style="color:var(--shiki-token-punctuation);">)</span></span></code></pre></div>
<h4 id="关键特性和方法">关键特性和方法<a aria-hidden="true" tabindex="-1" href="#关键特性和方法" class="internal"> §</a></h4>
<ol>
<li><strong>事务处理</strong>
<ul>
<li><code>commit()</code>: 提交当前事务。在执行如 INSERT、UPDATE、DELETE 等操作后,需要调用此方法以确保更改被保存。</li>
<li><code>rollback()</code>: 回滚当前事务。在遇到错误或需要撤销更改时使用。</li>
</ul>
</li>
<li><strong>连接管理</strong>
<ul>
<li><code>close()</code>: 关闭连接。关闭后,连接对象和其下所有的游标将不可用。</li>
</ul>
</li>
<li><strong>错误处理</strong>
<ul>
<li>连接操作可能会抛出 DB-API 定义的异常,如 <code>InterfaceError</code><code>DatabaseError</code></li>
</ul>
</li>
</ol>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 执行数据库操作</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 提交事务</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">Exception</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">rollback</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 回滚事务</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">raise</span><span style="color:var(--shiki-color-text);"> e</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">finally</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 关闭连接</span></span></code></pre></div>
<p>Python 进行数据库操作务必管理好数据库连接的生命周期。使用完毕后应及时关闭,避免资源泄露。建议使用 Python 的上下文管理器(<code>with</code> 语句)可以自动管理连接的开启和关闭。</p>
<h3 id="游标cursor">游标Cursor<a aria-hidden="true" tabindex="-1" href="#游标cursor" class="internal"> §</a></h3>
<p>游标是通过连接对象创建的,用于执行 SQL 命令和处理查询结果。</p>
<h4 id="创建游标">创建游标<a aria-hidden="true" tabindex="-1" href="#创建游标" class="internal"> §</a></h4>
<ul>
<li>通过连接对象的 <code>cursor()</code> 方法创建。</li>
<li>可以创建多个游标,用于执行不同的数据库操作。</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">cursor </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建游标</span></span></code></pre></div>
<h4 id="关键特性和方法-1">关键特性和方法<a aria-hidden="true" tabindex="-1" href="#关键特性和方法-1" class="internal"> §</a></h4>
<ol>
<li><strong>执行 SQL 命令</strong>
<ul>
<li><code>execute(sql, [parameters])</code>: 执行单个 SQL 命令。</li>
<li><code>executemany(sql, seq_of_parameters)</code>: 执行相同 SQL 命令多次,但使用不同的参数。</li>
</ul>
</li>
<li><strong>结果处理</strong>
<ul>
<li><code>fetchone()</code>: 返回结果集的下一行。</li>
<li><code>fetchmany(size)</code>: 返回结果集的下几行。</li>
<li><code>fetchall()</code>: 返回结果集中的所有行。</li>
</ul>
</li>
<li><strong>元数据获取</strong>
<ul>
<li>游标对象提供了诸如 <code>description</code> 属性,可以用来获取查询结果的列信息。</li>
</ul>
</li>
<li><strong>游标管理</strong>
<ul>
<li><code>close()</code>: 关闭游标。关闭后,游标将不可用。</li>
</ul>
</li>
</ol>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-comment);"># 执行 SQL 查询</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'SELECT * FROM some_table'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 获取查询结果</span></span>
<span data-line><span style="color:var(--shiki-color-text);">rows </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">fetchall</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 获取所有行</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> row </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> rows</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 关闭游标</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span></span></code></pre></div>
<p>为避免资源占用,执行完毕后应及时关闭游标。使用参数化查询而不是字符串拼接,以防止 SQL 注入攻击。</p>
<h3 id="执行-sql-语句execute">执行 SQL 语句execute<a aria-hidden="true" tabindex="-1" href="#执行-sql-语句execute" class="internal"> §</a></h3>
<p>在 Python 中,使用游标对象执行 SQL 语句并处理结果。</p>
<ul>
<li>使用游标对象的 <code>execute()</code> 方法执行 SQL 语句。</li>
<li>对于查询操作(如 SELECT结果可以通过游标提供的方法获取。</li>
<li>对于非查询操作(如 INSERT、UPDATE、DELETE结果通常是影响的行数。</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-comment);"># 执行一个查询</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'SELECT * FROM some_table'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 或者执行一个更新</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'UPDATE some_table SET column = value WHERE condition'</span><span style="color:var(--shiki-token-punctuation);">)</span></span></code></pre></div>
<h3 id="处理结果">处理结果<a aria-hidden="true" tabindex="-1" href="#处理结果" class="internal"> §</a></h3>
<ul>
<li>使用 <code>fetchone()</code><code>fetchmany(size)</code><code>fetchall()</code> 方法获取查询结果。</li>
<li><code>fetchone()</code> 返回单行,<code>fetchmany(size)</code> 返回指定数量的行,<code>fetchall()</code> 返回所有行。</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-comment);"># 执行查询</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'SELECT * FROM some_table'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 获取单行</span></span>
<span data-line><span style="color:var(--shiki-color-text);">row </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">fetchone</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 获取多行</span></span>
<span data-line><span style="color:var(--shiki-color-text);">rows </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">fetchmany</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> row </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> rows</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 获取所有行</span></span>
<span data-line><span style="color:var(--shiki-color-text);">all_rows </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">fetchall</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> row </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> all_rows</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span></code></pre></div>
<h3 id="错误处理">错误处理<a aria-hidden="true" tabindex="-1" href="#错误处理" class="internal"> §</a></h3>
<p>在 Python 数据库编程中错误处理是必不可少的部分。常见的数据库错误包括连接错误、SQL 语法错误、数据类型不匹配等。合理的错误处理可以提高程序的健壮性和用户体验。</p>
<ul>
<li>使用 <code>try-except</code> 块捕获并处理数据库异常。</li>
<li>利用 Python 的 DB-API 定义的异常类(如 <code>DatabaseError</code><code>IntegrityError</code> 等)来识别和响应特定的错误情况。</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'SELECT * FROM non_existent_table'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> sqlite3</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">DatabaseError </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Database error occurred:&quot;</span><span style="color:var(--shiki-token-punctuation);">, e)</span></span></code></pre></div>
<h4 id="调试数据库应用">调试数据库应用<a aria-hidden="true" tabindex="-1" href="#调试数据库应用" class="internal"> §</a></h4>
<ul>
<li>使用日志记录重要的操作和异常信息。</li>
<li>在开发阶段,打印或记录 SQL 语句和其参数,以便检查和调整。</li>
<li>使用交互式 Python 环境(如 IPython 或 Jupyter Notebook进行逐步执行和测试。</li>
</ul>
<h3 id="参数化查询">参数化查询<a aria-hidden="true" tabindex="-1" href="#参数化查询" class="internal"> §</a></h3>
<p>参数化查询是一种编写 SQL 查询的方法,可以提高安全性和灵活性。</p>
<h4 id="编写安全的-sql-查询以避免-sql-注入">编写安全的 SQL 查询以避免 SQL 注入<a aria-hidden="true" tabindex="-1" href="#编写安全的-sql-查询以避免-sql-注入" class="internal"> §</a></h4>
<p>通过使用占位符而非直接拼接字符串来构建 SQL 语句,可以有效防止 SQL 注入攻击。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-comment);"># 错误的做法:直接字符串拼接</span></span>
<span data-line><span style="color:var(--shiki-color-text);">unsafe_sql </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM users WHERE name = '&quot;</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">+</span><span style="color:var(--shiki-color-text);"> user_input </span><span style="color:var(--shiki-token-keyword);">+</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;'&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 正确的做法:使用参数化查询</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM users WHERE name = </span><span style="color:var(--shiki-token-constant);">%s</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">, (user_input,))</span></span></code></pre></div>
<h4 id="使用参数而非字符串拼接">使用参数而非字符串拼接<a aria-hidden="true" tabindex="-1" href="#使用参数而非字符串拼接" class="internal"> §</a></h4>
<p>在构建 SQL 语句时,应优先考虑使用参数化查询。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">user_id </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">5</span></span>
<span data-line><span style="color:var(--shiki-color-text);">cursor</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM users WHERE id = </span><span style="color:var(--shiki-token-constant);">%s</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">, (user_id,))</span></span></code></pre></div>
<h3 id="事务管理">事务管理<a aria-hidden="true" tabindex="-1" href="#事务管理" class="internal"> §</a></h3>
<h3 id="基本概念acid-特性">基本概念ACID 特性)<a aria-hidden="true" tabindex="-1" href="#基本概念acid-特性" class="internal"> §</a></h3>
<p>事务是数据库操作的基本单位,它应满足 ACID 特性即原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability</p>
<ul>
<li><strong>原子性</strong>:确保所有操作要么全部完成,要么全部不执行。</li>
<li><strong>一致性</strong>:事务完成时,数据必须处于一致状态。</li>
<li><strong>隔离性</strong>:多个事务同时进行时,一个事务的操作不应影响其他事务。</li>
<li><strong>持久性</strong>:一旦事务提交,其结果就永久保存在数据库中。</li>
</ul>
<h4 id="在-python-中进行事务控制">在 Python 中进行事务控制<a aria-hidden="true" tabindex="-1" href="#在-python-中进行事务控制" class="internal"> §</a></h4>
<p>在 Python 中事务控制通常由连接对象Connection来管理。使用 <code>commit()</code><code>rollback()</code> 方法来控制事务的提交和回滚。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">conn </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> sqlite3</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">connect</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'example.db'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 开始一个事务</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'INSERT INTO table_name VALUES (...)'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 更多数据库操作...</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 提交事务</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">Exception</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 出现错误,回滚事务</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">rollback</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">raise</span><span style="color:var(--shiki-color-text);"> e</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">finally</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 关闭连接</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span></span></code></pre></div>
<h3 id="数据库连接池">数据库连接池<a aria-hidden="true" tabindex="-1" href="#数据库连接池" class="internal"> §</a></h3>
<h4 id="理解数据库连接池的概念">理解数据库连接池的概念<a aria-hidden="true" tabindex="-1" href="#理解数据库连接池的概念" class="internal"> §</a></h4>
<p>数据库连接池是一种创建和管理数据库连接的技术,用于减少建立和关闭连接的开销。在高并发情况下,连接池可以显著提高性能。</p>
<h4 id="使用连接池提高性能">使用连接池提高性能<a aria-hidden="true" tabindex="-1" href="#使用连接池提高性能" class="internal"> §</a></h4>
<p>在 Python 中,可以使用第三方库(如 <code>sqlalchemy.pool</code>)来实现数据库连接池。连接池管理着一组连接,当需要时分配给请求者,使用完毕后返回池中。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">from</span><span style="color:var(--shiki-color-text);"> sqlalchemy</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">pool </span><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> QueuePool</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">from</span><span style="color:var(--shiki-color-text);"> sqlalchemy </span><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> create_engine</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 创建一个带连接池的引擎</span></span>
<span data-line><span style="color:var(--shiki-color-text);">engine </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_engine</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'postgresql://username:password@localhost/dbname'</span><span style="color:var(--shiki-token-punctuation);">, poolclass</span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-token-punctuation);">QueuePool)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 使用连接</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">with</span><span style="color:var(--shiki-color-text);"> engine</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">connect</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> connection</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> result </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> connection</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM table_name&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> row </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> result</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span></code></pre></div>
<h2 id="orm-工具">ORM 工具<a aria-hidden="true" tabindex="-1" href="#orm-工具" class="internal"> §</a></h2>
<p>在 Python 中对象关系映射Object-Relational Mapping, ORM是一种流行的技术它允许开发者以对象的形式操作数据库而无需编写 SQL 语句。ORMObject-Relational Mapping是一种<strong>将数据库表转换为程序中对象的技术</strong>,使开发者能够以面向对象的方式处理数据库。</p>
<table><thead><tr><th>ORM 库</th><th>简介</th><th>特点</th><th>适用场景</th></tr></thead><tbody><tr><td>Django ORM</td><td>Django 框架的一部分</td><td>无需编写 SQL支持多数据库丰富的查询构造器</td><td>Django 框架的 web 应用</td></tr><tr><td>SQLAlchemy</td><td>流行的独立 ORM 工具</td><td>灵活模型定义,强大查询,支持多数据库</td><td>适用于各种规模应用,特别是复杂数据库应用</td></tr><tr><td>Peewee</td><td>小巧但功能完整的 ORM 库</td><td>简单易用,学习曲线低</td><td>小型项目或简单 ORM 需求</td></tr><tr><td>Tortoise ORM</td><td>异步 ORM 库</td><td>支持异步操作,适合异步编程环境</td><td>需要高并发处理的现代 web 应用</td></tr><tr><td>Pony ORM</td><td>提供直观查询语言的 ORM 库</td><td>独特的查询语法,易于理解</td><td>寻求直观查询方式的开发者</td></tr></tbody></table>
<h3 id="基本的-orm-操作">基本的 ORM 操作<a aria-hidden="true" tabindex="-1" href="#基本的-orm-操作" class="internal"> §</a></h3>
<p>使用 ORM 工具时,开发者定义模型(即类),这些模型映射到数据库的表。在 Python 中,常见的 ORM 工具包括 SQLAlchemy 和 Django ORM。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">from</span><span style="color:var(--shiki-color-text);"> sqlalchemy </span><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> create_engine</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> Column</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> Integer</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> String</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">from</span><span style="color:var(--shiki-color-text);"> sqlalchemy</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">ext</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">declarative </span><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> declarative_base</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">from</span><span style="color:var(--shiki-color-text);"> sqlalchemy</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">orm </span><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> sessionmaker</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">Base </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">declarative_base</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);">engine </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_engine</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'sqlite:///example.db'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">Session </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">sessionmaker</span><span style="color:var(--shiki-token-punctuation);">(bind</span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-token-punctuation);">engine)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">User</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-function);">Base</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> __tablename__ </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'users'</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">id</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Column</span><span style="color:var(--shiki-token-punctuation);">(Integer, primary_key</span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-token-constant);">True</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> name </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Column</span><span style="color:var(--shiki-token-punctuation);">(String)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 创建表</span></span>
<span data-line><span style="color:var(--shiki-color-text);">Base</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">metadata</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">create_all</span><span style="color:var(--shiki-token-punctuation);">(engine)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 使用会话进行数据库操作</span></span>
<span data-line><span style="color:var(--shiki-color-text);">session </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Session</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);">new_user </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">User</span><span style="color:var(--shiki-token-punctuation);">(name</span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-token-string-expression);">'Alice'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">session</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">add</span><span style="color:var(--shiki-token-punctuation);">(new_user)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">session</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);">session</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span></span></code></pre></div>
<h2 id="项目实战">项目实战<a aria-hidden="true" tabindex="-1" href="#项目实战" class="internal"> §</a></h2>
<p>为了将所学知识应用于实际,可以从开发一个简单的数据库应用开始。例如,创建一个图书管理系统,包括图书的添加、查询、更新和删除功能。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> sqlite3</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">from</span><span style="color:var(--shiki-color-text);"> sqlite3 </span><span style="color:var(--shiki-token-keyword);">import</span><span style="color:var(--shiki-color-text);"> Error</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_connection</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">db_file</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot; 创建一个数据库连接到 SQLite 数据库 &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">None</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> sqlite3</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">connect</span><span style="color:var(--shiki-token-punctuation);">(db_file)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> conn</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> Error </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(e)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> conn</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_table</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">create_table_sql</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot; 创建表 &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> c </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> c</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(create_table_sql)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">except</span><span style="color:var(--shiki-color-text);"> Error </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(e)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">main</span><span style="color:var(--shiki-color-text);">():</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> database </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">r</span><span style="color:var(--shiki-token-string-expression);">&quot;pythonsqlite</span><span style="color:var(--shiki-token-constant);">.</span><span style="color:var(--shiki-token-string-expression);">db&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> sql_create_projects_table </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;&quot;&quot; CREATE TABLE IF NOT EXISTS projects (</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> id integer PRIMARY KEY,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> name text NOT NULL,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> begin_date text,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> end_date text</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> ); &quot;&quot;&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> sql_create_tasks_table </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;&quot;&quot;CREATE TABLE IF NOT EXISTS tasks (</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> id integer PRIMARY KEY,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> name text NOT NULL,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> priority integer,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> status_id integer NOT NULL,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> project_id integer NOT NULL,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> begin_date text NOT NULL,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> end_date text NOT NULL,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> FOREIGN KEY (project_id) REFERENCES projects (id)</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> );&quot;&quot;&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建一个数据库连接</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_connection</span><span style="color:var(--shiki-token-punctuation);">(database)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建表</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> conn </span><span style="color:var(--shiki-token-keyword);">is</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">not</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">None</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_table</span><span style="color:var(--shiki-token-punctuation);">(conn, sql_create_projects_table)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">create_table</span><span style="color:var(--shiki-token-punctuation);">(conn, sql_create_tasks_table)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">else</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;无法创建数据库连接。&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 插入数据</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> project </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-string-expression);">'Cool App with SQLite &amp; Python'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'2023-01-01'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'2023-12-31'</span><span style="color:var(--shiki-color-text);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> project_id </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">insert_project</span><span style="color:var(--shiki-token-punctuation);">(conn, project)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> task_1 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-string-expression);">'Analyze the requirements of the app'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> project_id</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'2023-01-01'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'2023-01-02'</span><span style="color:var(--shiki-color-text);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> task_2 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-string-expression);">'Confirm with user about the top priorities'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> project_id</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'2023-01-03'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'2023-01-05'</span><span style="color:var(--shiki-color-text);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 插入任务</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">insert_task</span><span style="color:var(--shiki-token-punctuation);">(conn, task_1)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">insert_task</span><span style="color:var(--shiki-token-punctuation);">(conn, task_2)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 查询数据</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;1. 查询项目:&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">select_all_projects</span><span style="color:var(--shiki-token-punctuation);">(conn)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;2. 查询任务:&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">select_all_tasks</span><span style="color:var(--shiki-token-punctuation);">(conn)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 更新数据</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">update_task</span><span style="color:var(--shiki-token-punctuation);">(conn, (</span><span style="color:var(--shiki-token-constant);">2</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-string-expression);">'2023-01-04'</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-constant);">2</span><span style="color:var(--shiki-token-punctuation);">))</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 删除数据</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">delete_task</span><span style="color:var(--shiki-token-punctuation);">(conn, </span><span style="color:var(--shiki-token-constant);">2</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 关闭连接</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">close</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">insert_project</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">project</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> 创建一个新的项目</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param conn:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param project:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :return: project id</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> sql </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">''' INSERT INTO projects(name,begin_date,end_date)</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> VALUES(?,?,?) '''</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(sql, project)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">lastrowid</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">insert_task</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">task</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> 创建一个新的任务</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param conn:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param task:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :return:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> sql </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">''' INSERT INTO tasks(name,priority,status_id,project_id,begin_date,end_date)</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> VALUES(?,?,?,?,?,?) '''</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(sql, task)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">lastrowid</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">select_all_projects</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> 查询所有项目</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param conn: the Connection object</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :return:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM projects&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> rows </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">fetchall</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> row </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> rows</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">select_all_tasks</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> 查询所有任务</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param conn: the Connection object</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :return:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;SELECT * FROM tasks&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> rows </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">fetchall</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> row </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> rows</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(row)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">update_task</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">task</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> 更新任务</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param conn:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param task:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :return: project id</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> sql </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">''' UPDATE tasks</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> SET priority = ? ,</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> end_date = ?</span></span>
<span data-line><span style="color:var(--shiki-token-string-expression);"> WHERE id = ?'''</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(sql, task)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">delete_task</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">conn</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">id</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">&quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> 删除一个任务通过任务 id</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param conn: Connection to the SQLite database</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :param id: id of the task</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> :return:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"> &quot;&quot;&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> sql </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'DELETE FROM tasks WHERE id=?'</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">cursor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cur</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">execute</span><span style="color:var(--shiki-token-punctuation);">(sql, (</span><span style="color:var(--shiki-token-function);">id</span><span style="color:var(--shiki-token-punctuation);">,))</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> conn</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">commit</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">__name__</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'__main__'</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">main</span><span style="color:var(--shiki-token-punctuation);">()</span></span></code></pre></div></article></div><div class="right sidebar"><div class="graph "><h3>Graph View</h3><div class="graph-outer"><div id="graph-container" data-cfg="{&quot;drag&quot;:true,&quot;zoom&quot;:true,&quot;depth&quot;:1,&quot;scale&quot;:1.1,&quot;repelForce&quot;:0.5,&quot;centerForce&quot;:0.3,&quot;linkDistance&quot;:30,&quot;fontSize&quot;:0.6,&quot;opacityScale&quot;:1,&quot;showTags&quot;:true,&quot;removeTags&quot;:[]}"></div><svg version="1.1" id="global-graph-icon" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 55 55" fill="currentColor" xmlSpace="preserve"><path d="M49,0c-3.309,0-6,2.691-6,6c0,1.035,0.263,2.009,0.726,2.86l-9.829,9.829C32.542,17.634,30.846,17,29,17
s-3.542,0.634-4.898,1.688l-7.669-7.669C16.785,10.424,17,9.74,17,9c0-2.206-1.794-4-4-4S9,6.794,9,9s1.794,4,4,4
c0.74,0,1.424-0.215,2.019-0.567l7.669,7.669C21.634,21.458,21,23.154,21,25s0.634,3.542,1.688,4.897L10.024,42.562
C8.958,41.595,7.549,41,6,41c-3.309,0-6,2.691-6,6s2.691,6,6,6s6-2.691,6-6c0-1.035-0.263-2.009-0.726-2.86l12.829-12.829
c1.106,0.86,2.44,1.436,3.898,1.619v10.16c-2.833,0.478-5,2.942-5,5.91c0,3.309,2.691,6,6,6s6-2.691,6-6c0-2.967-2.167-5.431-5-5.91
v-10.16c1.458-0.183,2.792-0.759,3.898-1.619l7.669,7.669C41.215,39.576,41,40.26,41,41c0,2.206,1.794,4,4,4s4-1.794,4-4
s-1.794-4-4-4c-0.74,0-1.424,0.215-2.019,0.567l-7.669-7.669C36.366,28.542,37,26.846,37,25s-0.634-3.542-1.688-4.897l9.665-9.665
C46.042,11.405,47.451,12,49,12c3.309,0,6-2.691,6-6S52.309,0,49,0z M11,9c0-1.103,0.897-2,2-2s2,0.897,2,2s-0.897,2-2,2
S11,10.103,11,9z M6,51c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S8.206,51,6,51z M33,49c0,2.206-1.794,4-4,4s-4-1.794-4-4
s1.794-4,4-4S33,46.794,33,49z M29,31c-3.309,0-6-2.691-6-6s2.691-6,6-6s6,2.691,6,6S32.309,31,29,31z M47,41c0,1.103-0.897,2-2,2
s-2-0.897-2-2s0.897-2,2-2S47,39.897,47,41z M49,10c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S51.206,10,49,10z"></path></svg></div><div id="global-graph-outer"><div id="global-graph-container" data-cfg="{&quot;drag&quot;:true,&quot;zoom&quot;:true,&quot;depth&quot;:-1,&quot;scale&quot;:0.9,&quot;repelForce&quot;:0.5,&quot;centerForce&quot;:0.3,&quot;linkDistance&quot;:30,&quot;fontSize&quot;:0.6,&quot;opacityScale&quot;:1,&quot;showTags&quot;:true,&quot;removeTags&quot;:[]}"></div></div></div><div class="toc desktop-only"><button type="button" id="toc" class><h3>Table of Contents</h3><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="fold"><polyline points="6 9 12 15 18 9"></polyline></svg></button><div id="toc-content"><ul class="overflow"><li class="depth-0"><a href="#python-db-api-20-规范概述" data-for="python-db-api-20-规范概述">Python DB-API 2.0 规范概述</a></li><li class="depth-1"><a href="#核心组件" data-for="核心组件">核心组件</a></li><li class="depth-1"><a href="#标准方法" data-for="标准方法">标准方法</a></li><li class="depth-1"><a href="#标准异常" data-for="标准异常">标准异常</a></li><li class="depth-0"><a href="#python-数据库操作" data-for="python-数据库操作">Python 数据库操作</a></li><li class="depth-1"><a href="#连接connection" data-for="连接connection">连接Connection</a></li><li class="depth-1"><a href="#游标cursor" data-for="游标cursor">游标Cursor</a></li><li class="depth-1"><a href="#执行-sql-语句execute" data-for="执行-sql-语句execute">执行 SQL 语句execute</a></li><li class="depth-1"><a href="#处理结果" data-for="处理结果">处理结果</a></li><li class="depth-1"><a href="#错误处理" data-for="错误处理">错误处理</a></li><li class="depth-1"><a href="#参数化查询" data-for="参数化查询">参数化查询</a></li><li class="depth-1"><a href="#事务管理" data-for="事务管理">事务管理</a></li><li class="depth-1"><a href="#基本概念acid-特性" data-for="基本概念acid-特性">基本概念ACID 特性)</a></li><li class="depth-1"><a href="#数据库连接池" data-for="数据库连接池">数据库连接池</a></li><li class="depth-0"><a href="#orm-工具" data-for="orm-工具">ORM 工具</a></li><li class="depth-1"><a href="#基本的-orm-操作" data-for="基本的-orm-操作">基本的 ORM 操作</a></li><li class="depth-0"><a href="#项目实战" data-for="项目实战">项目实战</a></li></ul></div></div><div class="backlinks "><h3>Backlinks</h3><ul class="overflow"><li>No backlinks found</li></ul></div><div class="explorer mobile-only"><button type="button" id="explorer" data-behavior="collapse" data-collapsed="collapsed" data-savestate="true" data-tree="[{&quot;path&quot;:&quot;Journal&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Journal/2024&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Journal/2024/W33&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Obsidian&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Obsidian/Templates&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2018&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2020&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2021&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2022&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2023&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2024&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Book&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Book/个人成长&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Book/医学健康&quot;,&quot;collapsed
function toggleCallout() {
const outerBlock = this.parentElement;
outerBlock.classList.toggle(`is-collapsed`);
const collapsed = outerBlock.classList.contains(`is-collapsed`);
const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight;
outerBlock.style.maxHeight = height + `px`;
let current = outerBlock;
let parent = outerBlock.parentElement;
while (parent) {
if (!parent.classList.contains(`callout`)) {
return;
}
const collapsed2 = parent.classList.contains(`is-collapsed`);
const height2 = collapsed2 ? parent.scrollHeight : parent.scrollHeight + current.scrollHeight;
parent.style.maxHeight = height2 + `px`;
current = parent;
parent = parent.parentElement;
}
}
function setupCallout() {
const collapsible = document.getElementsByClassName(
`callout is-collapsible`
);
for (const div of collapsible) {
const title = div.firstElementChild;
if (title) {
title.removeEventListener(`click`, toggleCallout);
title.addEventListener(`click`, toggleCallout);
const collapsed = div.classList.contains(`is-collapsed`);
const height = collapsed ? title.scrollHeight : div.scrollHeight;
div.style.maxHeight = height + `px`;
}
}
}
document.addEventListener(`nav`, setupCallout);
window.addEventListener(`resize`, setupCallout);
</script><script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark'
mermaid.initialize({
startOnLoad: false,
securityLevel: 'loose',
theme: darkMode ? 'dark' : 'default'
});
document.addEventListener('nav', async () => {
await mermaid.run({
querySelector: '.mermaid'
})
});
</script><script src="https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js" type="application/javascript"></script><script src="../../../../postscript.js" type="module"></script></html>