# Python SQLite 教程
> 原文: [http://zetcode.com/python/sqlite/](http://zetcode.com/python/sqlite/)
這是用于 SQLite 數據庫的 Python 編程教程。 它涵蓋了使用 Python 語言進行 SQLite 編程的基礎。 ZetCode 擁有用于 Python SQLite 的完整電子書: [Python SQLite 電子書](/ebooks/sqlitepython/)。
要使用本教程,我們必須在系統上安裝 Python 語言,SQLite 數據庫,`pysqlite`語言綁定和`sqlite3`命令行工具。
為了使用 SQLite 數據庫,我們可以安裝`sqlite3`或 SQLite 瀏覽器 GUI。
```py
$ python
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.version
'2.6.0'
>>> sqlite3.sqlite_version
'3.21.0'
```
在外殼程序中,我們啟動 Python 交互式解釋器。 我們可以看到 Python 版本。 在我們的例子中是 Python 3.7.0。 `sqlite.version`是`pysqlite`(2.6.0)的版本,它是 Python 語言與 SQLite 數據庫的綁定。 `sqlite3.sqlite_version`為我們提供了 SQLite 數據庫庫的版本。 在我們的例子中,版本是 3.21.0。
## SQLite
SQLite 是嵌入式關系數據庫引擎。 該文檔稱其為自包含,無服務器,零配置和事務型 SQL 數據庫引擎。 如今,它在全球使用著數億冊,非常受歡迎。 幾種編程語言都內置了對 SQLite 的支持,包括 Python 和 PHP。
## 創建 SQLite 數據庫
現在,我們將使用`sqlite3`命令行工具創建一個新數據庫。
```py
$ sqlite3 ydb.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite>
```
我們為`sqlite3 tool`提供了一個參數; `ydb.db`是數據庫名稱。 這是我們磁盤上的文件。 如果存在,則將其打開。 如果不是,則創建它。
```py
sqlite> .tables
sqlite> .exit
$ ls
ydb.db
```
`.tables`命令提供`ydb.db`數據庫中的表的列表。 當前沒有表格。 `.exit`命令終止`sqlite3`命令行工具的交互式會話。 `ls` Unix 命令顯示當前工作目錄的內容。 我們可以看到`ydb.db`文件。 所有數據將存儲在該單個文件中。
## Python SQLite 版本示例
在第一個代碼示例中,我們將獲得 SQLite 數據庫的版本。
`version.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
import sys
con = None
try:
con = sqlite.connect('ydb.db')
cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')
data = cur.fetchone()[0]
print(f"SQLite version: {data}")
except sqlite.Error as e:
print(f"Error {e.args[0]}")
sys.exit(1)
finally:
if con:
con.close()
```
在上面的 Python 腳本中,我們連接到先前創建的`ydb.db`數據庫。 我們執行一條 SQL 語句,該語句返回 SQLite 數據庫的版本。
```py
import sqlite3 as sqlite
```
我們導入`sqlite3`并為其命名。
```py
con = None
```
我們將`con`變量初始化為`None`。 如果無法創建與數據庫的連接(例如磁盤已滿),則不會定義連接變量。 這將導致`finally`子句中的錯誤。
```py
con = sqlite.connect('ydb.db')
```
我們連接到`ydb.db`數據庫。 `connect()`方法返回一個連接對象。
```py
cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')
```
從連接中,我們得到游標對象。 游標用于遍歷結果集中的記錄。 我們調用游標的`execute()`方法并執行 SQL 語句。
```py
data = cur.fetchone()[0]
```
我們獲取數據。 由于只檢索一條記錄,因此我們稱為`fetchone()`方法。
```py
print(f"SQLite version: {data}")
```
我們將檢索到的數據打印到控制臺。
```py
except sqlite.Error as e:
print(f"Error {e.args[0]}")
sys.exit(1)
```
如果發生異常,我們將輸出一條錯誤消息,并以錯誤代碼 1 退出腳本。
```py
finally:
if con:
con.close()
```
在最后一步,我們釋放資源。
在第二個示例中,我們再次獲得 SQLite 數據庫的版本。 這次我們將使用`with`關鍵字。
`version2.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')
data = cur.fetchone()[0]
print(f"SQLite version: {data}")
```
該腳本返回 SQLite 數據庫的當前版本。 通過使用`with`關鍵字。 代碼更緊湊。
```py
with con:
```
使用`with`關鍵字,Python 解釋器會自動釋放資源。 它還提供錯誤處理。
```py
$ ./version.py
SQLite version: 3.21.0
```
這是輸出。
## Python SQLite `execute`
我們創建一個`cars`表并在其中插入幾行。 我們使用`execute()`。
`create_table.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
cur.execute("INSERT INTO cars VALUES(1,'Audi',52642)")
cur.execute("INSERT INTO cars VALUES(2,'Mercedes',57127)")
cur.execute("INSERT INTO cars VALUES(3,'Skoda',9000)")
cur.execute("INSERT INTO cars VALUES(4,'Volvo',29000)")
cur.execute("INSERT INTO cars VALUES(5,'Bentley',350000)")
cur.execute("INSERT INTO cars VALUES(6,'Citroen',21000)")
cur.execute("INSERT INTO cars VALUES(7,'Hummer',41400)")
cur.execute("INSERT INTO cars VALUES(8,'Volkswagen',21600)")
```
上面的腳本創建一個`cars`表,并將 8 行插入到該表中。
```py
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
```
該 SQL 語句創建一個新的`cars`表。 該表有三列。
```py
cur.execute("INSERT INTO cars VALUES(1,'Audi',52642)")
cur.execute("INSERT INTO cars VALUES(2,'Mercedes',57127)")
```
這兩行將兩輛車插入表。 使用`with`關鍵字,更改將自動提交。 否則,我們將不得不手動提交它們。
```py
sqlite> .mode column
sqlite> .headers on
```
我們使用`sqlite3`工具驗證寫入的數據。 首先,我們修改數據在控制臺中的顯示方式。 我們使用列模式并打開標題。
```py
sqlite> select * from cars;
id name price
---------- ---------- ----------
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Citroen 21000
7 Hummer 41400
8 Volkswagen 21600
```
這是我們已寫入`cars`表的數據。
## Python SQLite `executemany`
我們將創建相同的表。 這次使用便捷的`executemany()`方法。
`create_table2.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
cars = (
(1, 'Audi', 52642),
(2, 'Mercedes', 57127),
(3, 'Skoda', 9000),
(4, 'Volvo', 29000),
(5, 'Bentley', 350000),
(6, 'Hummer', 41400),
(7, 'Volkswagen', 21600)
)
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)
```
程序將刪除`cars`表(如果存在)并重新創建它。
```py
cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
```
如果存在,則第一個 SQL 語句將刪除`cars`表。 第二條 SQL 語句創建`cars`表。
```py
cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)
```
我們使用便捷的`executemany()`方法將 8 行插入到表中。 此方法的第一個參數是參數化的 SQL 語句。 第二個參數是數據,以元組的元組的形式。
## Python SQLite `executescript`
我們提供了另一種使用`executescript()`創建`cars`表的方法。 我們手動提交更改并提供我們自己的錯誤處理。
`create_table3.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
import sys
con = None
try:
con = sqlite.connect('ydb.db')
cur = con.cursor()
cur.executescript("""
DROP TABLE IF EXISTS cars;
CREATE TABLE cars(id INT, name TEXT, price INT);
INSERT INTO cars VALUES(1,'Audi',52642);
INSERT INTO cars VALUES(2,'Mercedes',57127);
INSERT INTO cars VALUES(3,'Skoda',9000);
INSERT INTO cars VALUES(4,'Volvo',29000);
INSERT INTO cars VALUES(5,'Bentley',350000);
INSERT INTO cars VALUES(6,'Citroen',21000);
INSERT INTO cars VALUES(7,'Hummer',41400);
INSERT INTO cars VALUES(8,'Volkswagen',21600);
""")
con.commit()
except sqlite.Error as e:
if con:
con.rollback()
print(f"Error {e.args[0]}")
sys.exit(1)
finally:
if con:
con.close()
```
在上面的腳本中,我們使用`executescript()`方法(重新)創建`cars`表。
```py
cur.executescript("""
DROP TABLE IF EXISTS cars;
CREATE TABLE cars(id INT, name TEXT, price INT);
INSERT INTO cars VALUES(1,'Audi',52642);
INSERT INTO cars VALUES(2,'Mercedes',57127);
...
```
`executescript()`方法允許我們一步執行整個 SQL 代碼。
```py
con.commit()
```
如果沒有`with`關鍵字,則必須使用`commit()`方法來提交更改。
```py
except sqlite.Error as e:
if con:
con.rollback()
print(f"Error {e.args[0]}")
sys.exit(1)
```
發生錯誤時,所做的更改將回滾,并在終端上顯示一條錯誤消息。
## Python SQLite `lastrowid`
有時,我們需要確定最后插入的行的 ID。 在 Python SQLite 中,我們使用游標對象的`lastrowid`屬性。
`lastrowid.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect(':memory:')
with con:
cur = con.cursor()
cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT);")
cur.execute("INSERT INTO friends(name) VALUES ('Tom');")
cur.execute("INSERT INTO friends(name) VALUES ('Rebecca');")
cur.execute("INSERT INTO friends(name) VALUES ('Jim');")
cur.execute("INSERT INTO friends(name) VALUES ('Robert');")
last_row_id = cur.lastrowid
print(f"The last Id of the inserted row is {last_row_id}")
```
我們在內存中創建一個`friends`表。 ID 會自動遞增。
```py
cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT);")
```
在 SQLite 中,`INTEGER PRIMARY KEY`列自動增加。 還有一個`AUTOINCREMENT`關鍵字。 在`INTEGER PRIMARY KEY AUTOINCREMENT`中使用時,會使用稍微不同的 ID 創建算法。
```py
cur.execute("INSERT INTO friends(name) VALUES ('Tom');")
cur.execute("INSERT INTO friends(name) VALUES ('Rebecca');")
cur.execute("INSERT INTO friends(name) VALUES ('Jim');")
cur.execute("INSERT INTO friends(name) VALUES ('Robert');")
```
使用自動增量時,我們必須明確聲明列名,而忽略自動增量的列名。 這四個語句在`friends`表中插入四行。
```py
last_row_id = cur.lastrowid
```
使用`lastrowid`獲得最后插入的行 ID。
```py
$ ./lastrowid.py
The last Id of the inserted row is 4
```
我們看到了程序的輸出。
## Python SQLite 使用`fetchall`檢索數據
`fetchall()`方法獲取查詢結果集的所有(或所有剩余)行,并返回一個元組列表。
`fetch_all.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("SELECT * FROM cars")
rows = cur.fetchall()
for row in rows:
print(f"{row[0]} {row[1]} {row[2]}")
```
在此示例中,我們從`cars`表中檢索所有數據。
```py
cur.execute("SELECT * FROM cars")
```
該 SQL 語句從`cars`表中選擇所有數據。
```py
rows = cur.fetchall()
```
`fetchall()`方法獲取所有記錄。 它返回一個結果集。 從技術上講,它是一個元組的元組。 每個內部元組代表表中的一行。
```py
for row in rows:
print(f"{row[0]} {row[1]} {row[2]}")
```
我們將數據逐行打印到控制臺。
```py
$ ./fetch_all.py
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Citroen 21000
7 Hummer 41400
8 Volkswagen 21600
```
這是示例的輸出。
## Python SQLite `fetchone`
`fetchone()`返回查詢結果集的下一行,返回單個元組,或者在沒有更多數據可用時返回`None`。
`fetch_one.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("SELECT * FROM cars")
while True:
row = cur.fetchone()
if row == None:
break
print(f"{row[0]} {row[1]} {row[2]}")
```
在此腳本中,我們連接到數據庫,并逐個讀取`cars`表的行。
```py
while True:
```
我們從`while`循環訪問數據。 當我們讀取最后一行時,循環終止。
```py
row = cur.fetchone()
if row == None:
break
```
`fetchone()`方法返回表的下一行。 如果沒有剩余數據,則返回`None`。 在這種情況下,我們打破了循環。
```py
print(f"{row[0]} {row[1]} {row[2]}")
```
數據以元組的形式返回。 在這里,我們從元組中選擇記錄。 第一個是 ID,第二個是汽車名稱,第三個是汽車的價格。
```py
$ ./fetch_one.py
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Citroen 21000
7 Hummer 41400
8 Volkswagen 21600
```
這是示例的輸出。
## Python SQLite 字典游標
默認游標以元組的元組返回數據。 當我們使用字典游標時,數據以 Python 字典的形式發送。 這樣,我們可以通過列名稱來引用數據。
`dictionary_cursor.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
con.row_factory = sqlite.Row
cur = con.cursor()
cur.execute("SELECT * FROM cars")
rows = cur.fetchall()
for row in rows:
print(f"{row['id']} {row['name']} {row['price']}")
```
在此示例中,我們使用字典游標打印`cars`表的內容。
```py
con.row_factory = sqlite.Row
```
我們選擇一個字典游標。 現在,我們可以按列名訪問記錄。
```py
for row in rows:
print(f"{row['id']} {row['name']} {row['price']}")
```
通過列名訪問數據。
## Python SQLite 參數化語句
現在,我們將關注參數化查詢。 當使用參數化查詢時,我們使用占位符,而不是直接將值寫入語句。 參數化查詢可提高安全性和性能。
Python `sqlite3`模塊支持兩種類型的占位符:問號和命名占位符。
### 帶問號的參數化語句
在第一個示例中,我們使用問號的語法。
`parameterized_query.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
uId = 1
uPrice = 62300
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("UPDATE cars SET price=? WHERE id=?", (uPrice, uId))
print(f"Number of rows updated: {cur.rowcount}")
```
我們更新了一輛車的價格。 在此代碼示例中,我們使用問號占位符。
```py
cur.execute("UPDATE cars SET price=? WHERE id=?", (uPrice, uId))
```
問號`?`是值的占位符。 這些值將添加到占位符。
```py
print(f"Number of rows updated: {cur.rowcount}")
```
`rowcount`屬性返回更新的行數。 在我們的情況下,一行已更新。
### 具有命名占位符的參數化語句
第二個示例使用帶有命名占位符的參數化語句。
`named_placeholders.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
uId = 4
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("SELECT name, price FROM cars WHERE Id=:Id", {"Id": uId})
row = cur.fetchone()
print(f"{row[0]}, {row[1]}")
```
我們使用命名的占位符選擇汽車的名稱和價格。
```py
cur.execute("SELECT name, price FROM cars WHERE Id=:Id", {"Id": uId})
```
命名的占位符以冒號開頭。
## Python SQLite 插入圖片
在本節中,我們將圖像插入到 SQLite 數據庫中。 請注意,有些人反對將圖像放入數據庫。 在這里,我們只展示如何做。 我們不討論是否將圖像保存在數據庫中的技術問題。
```py
sqlite> CREATE TABLE images(id INTEGER PRIMARY KEY, data BLOB);
```
對于此示例,我們創建一個名為`Images`的新表。 對于圖像,我們使用`BLOB`數據類型,表示二進制大型對象。
`insert_image.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
import sys
def readImage():
fin = None
try:
fin = open("sid.jpg", "rb")
img = fin.read()
return img
except IOError as e:
print(e)
sys.exit(1)
finally:
if fin:
fin.close()
con = None
try:
con = sqlite.connect('ydb.db')
cur = con.cursor()
data = readImage()
binary = sqlite.Binary(data)
cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )
con.commit()
except sqlite.Error as e:
if con:
con.rollback()
print(e)
sys.exit(1)
finally:
if con:
con.close()
```
在此腳本中,我們從當前工作目錄中讀取圖像,并將其寫入 SQLite `ydb.db`數據庫的`images`表中。
```py
try:
fin = open("sid.png", "rb")
img = fin.read()
return img
```
我們從文件系統讀取二進制數據。 我們有一個名為`sid.png`的 JPG 圖像。
```py
binary = sqlite.Binary(data)
```
使用 SQLite `Binary`對象對數據進行編碼。
```py
cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )
```
該 SQL 語句用于將映像插入數據庫。
## Python SQLite 讀取圖像
在本節中,我們將執行相反的操作:我們從數據庫表中讀取一個圖像。
`read_image.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
import sys
def writeImage(data):
fout = None
try:
fout = open('sid2.png','wb')
fout.write(data)
except IOError as e:
print(e)
sys.exit(1)
finally:
if fout:
fout.close()
con = None
try:
con = sqlite.connect('ydb.db')
cur = con.cursor()
cur.execute("SELECT data FROM images LIMIT 1")
data = cur.fetchone()[0]
writeImage(data)
except sqlite.Error as e:
print(e)
sys.exit(1)
finally:
if con:
con.close()
```
我們從`Images`表中讀取圖像數據,并將其寫入另一個文件`woman2.jpg`中。
```py
try:
fout = open('sid2.png','wb')
fout.write(data)
```
我們以寫入模式打開一個二進制文件。 來自數據庫的數據被寫入文件。
```py
cur.execute("SELECT data FROM images LIMIT 1")
data = cur.fetchone()[0]
```
這兩行從`images`表中選擇并獲取數據。 我們從第一行獲取二進制數據。
## Python SQLite 元數據
元數據是有關數據庫中數據的信息。 SQLite 中的元數據包含有關表和列的信息,我們在其中存儲數據。 受 SQL 語句影響的行數是元數據。 結果集中返回的行數和列數也屬于元數據。
可以使用`PRAGMA`命令獲取 SQLite 中的元數據。 SQLite 對象可能具有屬性,即元數據。 最后,我們還可以通過查詢 SQLite 系統`sqlite_master`表來獲取特定的元數據。
`column_names.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute('PRAGMA table_info(cars)')
data = cur.fetchall()
for d in data:
print(f"{d[0]} {d[1]} {d[2]}")
```
在此示例中,我們發出`PRAGMA table_info(tableName)`命令,以獲取有關`cars`表的一些元數據信息。
```py
cur.execute('PRAGMA table_info(cars)')
```
`PRAGMA table_info(tableName)`命令為`cars`表中的每一列返回一行。 結果集中的列包括列順序號,列名稱,數據類型,該列是否可以為`NULL`以及該列的默認值。
```py
for d in data:
print(f"{d[0]} {d[1]} {d[2]}")
```
根據提供的信息,我們打印列順序號,列名稱和列數據類型。
```py
$ ./column_names.py
0 id INT
1 name TEXT
2 price INT
```
這是示例的輸出。
在下面的示例中,我們打印`cars`表中的所有行及其列名。
`column_names2.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute('SELECT * FROM cars')
col_names = [cn[0] for cn in cur.description]
rows = cur.fetchall()
print(f"{col_names[0]:3} {col_names[1]:10} {col_names[2]:7}")
for row in rows:
print(f"{row[0]:<3} {row[1]:<10} {row[2]:7}")
```
我們將`cars`表的內容打印到控制臺。 現在,我們也包括列的名稱。 記錄與列名對齊。
```py
col_names = [cn[0] for cn in cur.description]
```
我們從游標對象的`description`屬性獲得列名。
```py
print(f"{col_names[0]:3} {col_names[1]:10} {col_names[2]:7}")
```
此行打印`cars`表的三個列名。
```py
for row in rows:
print(f"{row[0]:<3} {row[1]:<10} {row[2]:7}")
```
我們使用`for`循環打印行。 數據與列名對齊。
```py
$ ./column_names2.py
id name price
1 Audi 62300
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Hummer 41400
7 Volkswagen 21600
```
這是輸出。
在與元數據有關的最后一個示例中,我們將列出`ydb.db`數據庫中的所有表。
`list_tables.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
cur.execute("SELECT name FROM sqlite_master WHERE type='table'")
rows = cur.fetchall()
for row in rows:
print(row[0])
```
該代碼示例將當前數據庫中的所有可用表打印到終端。
```py
cur.execute("SELECT name FROM sqlite_master WHERE type='table'")
```
表名存儲在系統`sqlite_master`表中。
```py
$ ./list_tables.py
cars
images
```
這些是我們系統上的表。
## Python SQLite 數據導出
我們可以轉儲 SQL 格式的數據以創建數據庫表的簡單備份。
`export_table.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
cars = (
(1, 'Audi', 52643),
(2, 'Mercedes', 57642),
(3, 'Skoda', 9000),
(4, 'Volvo', 29000),
(5, 'Bentley', 350000),
(6, 'Hummer', 41400),
(7, 'Volkswagen', 21600)
)
def writeData(data):
f = open('cars.sql', 'w')
with f:
f.write(data)
con = sqlite.connect(':memory:')
with con:
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)
cur.execute("DELETE FROM cars WHERE price < 30000")
data = '\n'.join(con.iterdump())
writeData(data)
```
在上面的示例中,我們在內存中重新創建了`cars`表。 我們從表中刪除一些行,并將表的當前狀態轉儲到`cars.sql`文件中。 該文件可以用作表的當前備份。
```py
def writeData(data):
f = open('cars.sql', 'w')
with f:
f.write(data)
```
表中的數據正在寫入文件。
```py
con = sqlite.connect(':memory:')
```
我們在內存中創建一個臨時表。
```py
cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)
cur.execute("DELETE FROM cars WHERE price < 30000")
```
這些行創建`cars`表,插入值并刪除行,其中`price`小于 30000 單位。
```py
data = '\n'.join(con.iterdump())
```
`con.iterdump()`返回一個迭代器,以 SQL 文本格式轉儲數據庫。 內置的`join()`函數采用迭代器,并將迭代器中的所有字符串連接在一起,并用新行分隔。 此數據將寫入`writeData()`函數中的`cars.sql`文件中。
```py
$ cat cars.sql
BEGIN TRANSACTION;
CREATE TABLE cars(id INT, name TEXT, price INT);
INSERT INTO "cars" VALUES(1,'Audi',52643);
INSERT INTO "cars" VALUES(2,'Mercedes',57642);
INSERT INTO "cars" VALUES(5,'Bentley',350000);
INSERT INTO "cars" VALUES(6,'Hummer',41400);
COMMIT;
```
廢棄的內存車表中的內容。
## Python SQLite 導入數據
現在,我們將執行反向操作。 我們將轉儲的表導入回內存。
`import_table.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
def readData():
f = open('cars.sql', 'r')
with f:
data = f.read()
return data
con = sqlite.connect(':memory:')
with con:
cur = con.cursor()
sql = readData()
cur.executescript(sql)
cur.execute("SELECT * FROM cars")
rows = cur.fetchall()
for row in rows:
print(row)
```
在此腳本中,我們讀取`cars.sql`文件的內容并執行它。 這將重新創建轉儲的表。
```py
def readData():
f = open('cars.sql', 'r')
with f:
data = f.read()
return data
```
在`readData()`方法內部,我們讀取`cars.sql`表的內容。
```py
cur.executescript(sql)
```
我們調用`executescript()`方法來啟動 SQL 腳本。
```py
cur.execute("SELECT * FROM cars")
rows = cur.fetchall()
for row in rows:
print(row)
```
我們驗證數據。
```py
$ ./import_table.py
(1, u'Audi', 52643)
(2, u'Mercedes', 57642)
(5, u'Bentley', 350000)
(6, u'Hummer', 41400)
```
輸出顯示我們已經成功地重新創建了保存的汽車表。
## Python SQLite 事務
事務是針對一個或多個數據庫中數據的數據庫操作的基本單位。 事務中所有 SQL 語句的影響可以全部提交給數據庫,也可以全部回滾。
默認情況下,Python `sqlite3`模塊在數據修改語言(DML)語句(即`INSERT`/`UPDATE`/`DELETE`/`REPLACE`)之前隱式發出`BEGIN`語句。
`sqlite3`用于在 DDL 語句之前隱式提交一個打開的事務。 這已不再是這種情況。
手動事務以`BEGIN TRANSACTION`語句開始,并以`COMMIT`或`ROLLBACK`語句結束。
SQLite 支持三種非標準事務級別:`DEFERRED`,`IMMEDIATE`和`EXCLUSIVE`。 Python SQLite 模塊還支持自動提交模式,該模式下對表的所有更改均立即生效。
`no_commit.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
import sys
con = None
try:
con = sqlite.connect('ydb.db')
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS friends")
cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)")
cur.execute("INSERT INTO friends(name) VALUES ('Tom')")
cur.execute("INSERT INTO friends(name) VALUES ('Rebecca')")
cur.execute("INSERT INTO friends(name) VALUES ('Jim')")
cur.execute("INSERT INTO friends(name) VALUES ('Robert')")
#con.commit()
except sqlite.Error as e:
if con:
con.rollback()
print(e)
sys.exit(1)
finally:
if con:
con.close()
```
我們創建一個`friends`表,并嘗試用數據填充它。 但是,正如我們將看到的,數據未提交。
```py
#con.commit()
```
注釋`commit()`方法。 如果我們取消注釋該行,則數據將被寫入表中。
```py
sqlite> .tables
cars friends images
sqlite> SELECT Count(id) FROM friends;
Count(id)
----------
0
sqlite>
```
表已創建,但數據未寫入表中。
### Python SQLite 自動提交
在自動提交模式下,將立即執行一條 SQL 語句。
`autocommit.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3 as sqlite
import sys
con = None
try:
con = sqlite.connect('ydb.db', isolation_level=None)
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS friends")
cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)")
cur.execute("INSERT INTO friends(name) VALUES ('Tom')")
cur.execute("INSERT INTO friends(name) VALUES ('Rebecca')")
cur.execute("INSERT INTO friends(name) VALUES ('Jim')")
cur.execute("INSERT INTO friends(name) VALUES ('Robert')")
except sqlite.Error as e:
print(e)
sys.exit(1)
finally:
if con:
con.close()
```
在此示例中,我們以自動提交模式連接到數據庫。
```py
con = sqlite.connect('ydb.db', isolation_level=None)
```
當將`isolation_level`設置為`None`時,我們具有自動提交模式。
```py
$ ./autocommit.py
sqlite> SELECT * FROM friends;
Id Name
---------- ----------
1 Tom
2 Rebecca
3 Jim
4 Robert
```
數據已成功提交到`friends`表。
這是 Python SQLite 教程。
您可能還想查看 ZetCode 上的 [Python 教程](/lang/python/), [PyMySQL 教程](/python/pymysql/)或 [Python PostgreSQL 教程](/python/psycopg2/)。
- ZetCode 數據庫教程
- MySQL 教程
- MySQL 簡介
- MySQL 安裝
- MySQL 的第一步
- MySQL 快速教程
- MySQL 存儲引擎
- MySQL 數據類型
- 在 MySQL 中創建,更改和刪除表
- MySQL 表達式
- 在 MySQL 中插入,更新和刪除數據
- MySQL 中的SELECT語句
- MySQL 子查詢
- MySQL 約束
- 在 MySQL 中導出和導入數據
- 在 MySQL 中連接表
- MySQL 函數
- MySQL 中的視圖
- MySQL 中的事務
- MySQL 存儲過程
- MySQL Python 教程
- MySQL Perl 教程
- MySQL & Perl DBI
- 使用 Perl 連接到 MySQL 數據庫
- MySQL 中的 Perl 錯誤處理
- 使用 Perl 進行 MySQL 查詢
- 在 MySQL 中使用 Perl 綁定參數&列
- 在 MySQL 中使用 Perl 處理圖像
- 使用 Perl 獲取 MySQL 元數據
- Perl 的 MySQL 事務
- MySQL C API 編程教程
- MySQL Visual Basic 教程
- MySQL PHP 教程
- MySQL Java 教程
- MySQL Ruby 教程
- MySQL C# 教程
- SQLite 教程
- SQLite 簡介
- sqlite3 命令行工具
- 在 SQLite 中創建,刪除和更改表
- SQLite 表達式
- SQLite 插入,更新,刪除數據
- SQLite SELECT語句
- SQLite 約束
- SQLite 連接表
- SQLite 函數
- SQLite 視圖,觸發器,事務
- SQLite C 教程
- SQLite Python 教程
- SQLite Perl 教程
- Perl DBI
- 使用 Perl 連接到 SQLite 數據庫
- SQLite Perl 錯誤處理
- 使用 Perl 的 SQLite 查詢
- 使用 Perl 綁定 SQLite 參數&列
- 使用 Perl 在 SQLite 中處理圖像
- 使用 Perl 獲取 SQLite 元數據
- 使用 Perl 進行 SQLite 事務
- SQLite Ruby 教程
- 連接到 SQLite 數據庫
- 在 SQLite 中使用 Ruby 進行 SQL 查詢
- 綁定參數
- 處理圖像
- 使用 Ruby 獲取 SQLite 元數據
- Ruby 的 SQLite 事務
- SQLite C# 教程
- SQLite C# 簡介
- 使用SqliteDataReader檢索數據
- ADO.NET 數據集
- 使用 C# 在 SQLite 中處理圖像
- 使用 C# 獲取 SQLite 元數據
- 使用 C# 的 SQLite 事務
- SQLite Visual Basic 教程
- SQLite Visual Basic 簡介
- 使用SqliteDataReader檢索數據
- ADO.NET 的數據集
- 使用 Visual Basic 在 SQLite 中處理圖像
- 使用 Visual Basic 獲取 SQLite 元數據
- 使用 Visual Basic 的 SQLite 事務
- PostgreSQL C 教程
- PostgreSQL Ruby 教程
- PostgreSQL PHP 教程
- PostgreSQL PHP 編程簡介
- 在 PostgreSQL 中使用 PHP 檢索數據
- 在 PostgreSQL 中使用 PHP 處理圖像
- 用 PHP 獲取 PostgreSQL 元數據
- 在 PostgreSQL 中使用 PHP 進行事務
- PostgreSQL Java 教程
- Apache Derby 教程
- Derby 簡介
- Derby 的安裝&配置
- Derby 工具
- ij 工具
- Derby 中的 SQL 查詢
- 在 Derby 中使用 JDBC 進行編程
- Derby 安全
- 使用 Derby & Apache Tomcat
- NetBeans 和 Derby
- SQLAlchemy 教程
- SQLAlchemy 簡介
- 原始 SQL
- 模式定義語言
- SQL 表達式語言
- SQLAlchemy 中的對象關系映射器
- MongoDB PHP 教程
- MongoDB JavaScript 教程
- MongoDB Ruby 教程
- Spring JdbcTemplate 教程
- JDBI 教程
- MyBatis 教程
- Hibernate Derby 教程
- ZetCode .NET 教程
- Visual Basic 教程
- Visual Basic
- Visual Basic 語法結構
- 基本概念
- Visual Basic 數據類型
- Visual Basic 中的字符串
- 運算符
- 控制流
- Visual Basic 數組
- Visual Basic 中的過程&函數
- 在 Visual Basic 中組織代碼
- 面向對象編程
- Visual Basic 中的面向對象編程 II
- Visual Basic 中的集合
- 輸入和輸出
- C# 教程
- C# 語言
- C# 語法結構
- C# 基礎
- C# 數據類型
- C# 中的字符串
- C# 運算符
- C# 中的流控制
- C# 數組
- C# 面向對象編程
- C# 中的方法
- C# 面向對象編程 II
- C# 屬性
- C# 結構
- C# 委托
- 命名空間
- C# 集合
- C# 輸入和輸出
- C# 目錄教程
- C# 字典教程
- 在 C# 中讀取文本文件
- C# 中的日期和時間
- 在 C# 中讀取網頁
- C# HttpClient教程
- ASP.NET Core 教程
- ZetCode 圖形教程
- Java 2D 游戲教程
- Java 游戲基礎
- 動畫
- 移動精靈
- 碰撞檢測
- Java 益智游戲
- Java Snake
- Breakout 游戲
- Java 俄羅斯方塊
- Java 吃豆人
- Java 太空侵略者
- Java 掃雷
- Java 推箱子
- Java 2D 教程
- 介紹
- 基本繪圖
- 形狀和填充
- 透明度
- 合成
- 剪裁
- 變換
- 特效
- 圖像
- 文字和字體
- 命中測試,移動物體
- 俄羅斯方塊
- Cario 圖形教程
- Cario 圖形庫
- Cario 定義
- Cairo 后端
- Cairo 基本圖形
- 形狀和填充
- 漸變
- 透明度
- 合成
- 剪裁和遮罩
- 變換
- Cairo 文字
- Cairo 中的圖像
- 根窗口
- PyCairo 教程
- PyCairo 簡介
- PyCairo 后端
- PyCairo 中的基本繪圖
- PyCairo 形狀和填充
- PyCairo 漸變
- PyCairo 剪裁&遮罩
- PyCairo 的透明度
- PyCairo 中的變換
- PyCairo 中的文字
- PyCairo 中的圖像
- 根窗口
- HTML5 畫布教程
- 介紹
- HTML5 畫布中的直線
- HTML5 畫布形狀
- HTML5 畫布填充
- HTML5 畫布中的透明度
- HTML5 畫布合成
- HTML5 canvas 中的變換
- HTML5 畫布中的文字
- HTML5 畫布中的動畫
- HTML5 畫布中的 Snake
- ZetCode GUI 教程
- Windows API 教程
- Windows API 簡介
- Windows API main函數
- Windows API 中的系統函數
- Windows API 中的字符串
- Windows API 中的日期和時間
- Windows API 中的一個窗口
- UI 的第一步
- Windows API 菜單
- Windows API 對話框
- Windows API 控件 I
- Windows API 控件 II
- Windows API 控件 III
- Windows API 中的高級控件
- Windows API 中的自定義控件
- Windows API 中的 GDI
- PyQt4 教程
- PyQt4 簡介
- PyQt4 中的第一個程序
- PyQt4 中的菜單和工具欄
- PyQt4 中的布局管理
- PyQt4 中的事件和信號
- PyQt4 中的對話框
- PyQt4 小部件
- PyQt4 小部件 II
- PyQt4 中的拖放
- PyQt4 中的繪圖
- PyQt4 中的自定義小部件
- PyQt4 中的俄羅斯方塊游戲
- PyQt5 教程
- PyQt5 簡介
- PyQt5 日期和時間
- PyQt5 中的第一個程序
- PyQt5 中的菜單和工具欄
- PyQt5 中的布局管理
- PyQt5 中的事件和信號
- PyQt5 中的對話框
- PyQt5 小部件
- PyQt5 小部件 II
- PyQt5 拖放
- PyQt5 中的繪圖
- PyQt5 中的自定義小部件
- PyQt5 中的俄羅斯方塊
- Qt4 教程
- Qt4 工具包簡介
- Qt4 工具類
- Qt4 中的字符串
- Qt4 中的日期和時間
- 在 Qt4 中使用文件和目錄
- Qt4 中的第一個程序
- Qt4 中的菜單和工具欄
- Qt4 中的布局管理
- Qt4 中的事件和信號
- Qt4 小部件
- Qt4 小部件 II
- Qt4 中的繪圖
- Qt4 中的自定義小部件
- Qt4 中的打磚塊游戲
- Qt5 教程
- Qt5 工具包簡介
- Qt5 中的字符串
- Qt5 中的日期和時間
- Qt5 中的容器
- 在 Qt5 中處理文件和目錄
- Qt5 中的第一個程序
- Qt5 中的菜單和工具欄
- Qt5 中的布局管理
- Qt5 中的事件和信號
- Qt5 小部件
- Qt5 小部件 II
- Qt5 中的繪圖
- Qt5 中的自定義小部件
- Qt5 中的貪食蛇
- Qt5 中的打磚塊游戲
- PySide 教程
- PySide 工具包簡介
- PySide 中的第一個程序
- PySide 中的菜單和工具欄
- PySide 中的布局管理
- PySide 中的事件和信號
- PySide 中的對話框
- PySide 小部件
- PySide 小部件 II
- 在 PySide 中拖放
- 在 PySide 中繪圖
- PySide 中的自定義小部件
- PySide 中的俄羅斯方塊游戲
- Tkinter 教程
- Tkinter 簡介
- Tkinter 中的布局管理
- Tkinter 標準小部件屬性
- Tkinter 小部件
- Tkinter 中的菜單和工具欄
- Tkinter 中的對話框
- Tkinter 中的繪圖
- Tkinter 中的貪食蛇
- Tcl/Tk 教程
- Tcl/Tk 簡介
- Tcl/Tk 中的布局管理
- Tcl/Tk 小部件
- Tcl/Tk 中的菜單和工具欄
- Tcl/Tk 中的對話框
- Tcl/Tk 繪圖
- 貪食蛇
- Qt 快速教程
- Java Swing 教程
- Java Swing 簡介
- Java Swing 首個程序
- Java Swing 中的菜單和工具欄
- Swing 布局管理
- GroupLayout管理器
- Java Swing 事件
- 基本的 Swing 組件
- 基本的 Swing 組件 II
- Java Swing 對話框
- Java Swing 模型架構
- Swing 中的拖放
- Swing 中的繪圖
- Java Swing 中的可調整大小的組件
- Java Swing 中的益智游戲
- 俄羅斯方塊
- JavaFX 教程
- JavaFX 簡介
- JavaFX 首個程序
- JavaFX 布局窗格
- 基本的 JavaFX 控件
- 基本 JavaFX 控件 II
- JavaFX 事件
- JavaFX 效果
- JavaFX 動畫
- JavaFX 畫布
- JavaFX 圖表
- Java SWT 教程
- Java SWT 簡介
- Java SWT 中的布局管理
- Java SWT 中的菜單和工具欄
- Java SWT 中的小部件
- Table小部件
- Java SWT 中的對話框
- Java SWT 繪圖
- Java SWT 中的貪食蛇
- wxWidgets 教程
- wxWidgets 簡介
- wxWidgets 助手類
- wxWidgets 中的第一個程序
- wxWidgets 中的菜單和工具欄
- wxWidgets 中的布局管理
- wxWidgets 中的事件
- wxWidgets 中的對話框
- wxWidgets 小部件
- wxWidgets 小部件 II
- wxWidgets 中的拖放
- wxWidgets 中的設備上下文
- wxWidgets 中的自定義小部件
- wxWidgets 中的俄羅斯方塊游戲
- wxPython 教程
- wxPython 簡介
- 第一步
- 菜單和工具欄
- wxPython 中的布局管理
- wxPython 中的事件
- wxPython 對話框
- 小部件
- wxPython 中的高級小部件
- wxPython 中的拖放
- wxPython 圖形
- 創建自定義小部件
- wxPython 中的應用框架
- wxPython 中的俄羅斯方塊游戲
- C# Winforms Mono 教程
- Mono Winforms 簡介
- Mono Winforms 中的第一步
- Mono Winforms 中的布局管理
- Mono Winforms 中的菜單和工具欄
- Mono Winforms 中的基本控件
- Mono Winforms 中的高級控件
- 對話框
- Mono Winforms 中的拖放
- Mono Winforms 中的繪圖
- Mono Winforms 中的貪食蛇
- Java Gnome 教程
- Java Gnome 簡介
- Java Gnome 的第一步
- Java Gnome 中的布局管理
- Java Gnome 中的布局管理 II
- Java Gnome 中的菜單
- Java Gnome 中的工具欄
- Java Gnome 中的事件
- Java Gnome 中的小部件
- Java Gnome 中的小部件 II
- Java Gnome 中的高級小部件
- Java Gnome 中的對話框
- Java Gnome 中的 Pango
- 在 Java Gnome 中用 Cairo 繪圖
- Cario 繪圖 II
- Java Gnome 中的貪食蛇
- QtJambi 教程
- QtJambi 簡介
- QtJambi 中的布局管理
- QtJambi 中的小部件
- QtJambi 中的菜單和工具欄
- QtJambi 對話框
- QtJambi 中的繪圖
- QtJambi 中的自定義小部件
- 貪食蛇
- GTK+ 教程
- GTK+ 簡介
- GTK+ 中的第一個程序
- GTK+ 中的菜單和工具欄
- GTK+ 布局管理
- GTK+ 事件和信號
- GTK+ 對話框
- GTK+ 小部件
- GTK+ 小部件 II
- GtkTreeView小部件
- GtkTextView小部件
- 自定義 GTK+ 小部件
- Ruby GTK 教程
- Ruby GTK 簡介
- Ruby GTK 中的布局管理
- Ruby GTK 中的小部件
- Ruby GTK 中的菜單和工具欄
- Ruby GTK 中的對話框
- Ruby GTK Cario 繪圖
- Ruby GTK 中的自定義小部件
- Ruby GTK 中的貪食蛇
- GTK# 教程
- GTK# 簡介
- GTK 的第一步
- GTK# 中的布局管理
- GTK 中的菜單
- GTK# 中的工具欄
- GTK# 中的事件
- GTK# 中的小部件
- GTK 中的小部件 II
- GTK# 中的高級小部件
- GTK# 中的對話框
- Pango
- GTK# 中的 Cario 繪圖
- GTK# 中的 Cario 繪圖 II
- GTK# 中的自定義小部件
- Visual Basic GTK# 教程
- Visual Basic GTK# 簡介
- 布局管理
- 小部件
- 菜單和工具欄
- 對話框
- Cario 繪圖
- 自定義小部件
- 貪食蛇
- PyGTK 教程
- PyGTK 簡介
- PyGTK 的第一步
- PyGTK 中的布局管理
- PyGTK 中的菜單
- PyGTK 中的工具欄
- PyGTK 中的事件和信號
- PyGTK 中的小部件
- PyGTK 中的小部件 II
- PyGTK 中的高級小部件
- PyGTK 中的對話框
- Pango
- Pango II
- PyGTK 中的 Cario 繪圖
- Cario 繪圖 II
- PyGTK 中的貪食蛇游戲
- PyGTK 中的自定義小部件
- PHP GTK 教程
- PHP GTK 簡介
- PHP GTK 中的布局管理
- PHP GTK 中的小部件
- PHP GTK 中的菜單和工具欄
- 對話框
- Cario 繪圖
- 自定義小部件
- 貪食蛇
- C# Qyoto 教程
- Qyoto 介紹
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜單和工具欄
- Qyoto 對話框
- Qyoto 中的繪圖
- Qyoto 中的繪圖 II
- Qyoto 中的自定義小部件
- 貪食蛇
- Ruby Qt 教程
- Ruby Qt 簡介
- Ruby Qt 中的布局管理
- Ruby Qt 中的小部件
- 菜單和工具欄
- Ruby Qt 中的對話框
- 用 Ruby Qt 繪圖
- Ruby Qt 中的自定義小部件
- Ruby Qt 中的貪食蛇
- Visual Basic Qyoto 教程
- Qyoto 介紹
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜單和工具欄
- Qyoto 對話框
- Qyoto 中的繪圖
- Qyoto 中的自定義小部件
- 貪食蛇
- Mono IronPython Winforms 教程
- 介紹
- IronPython Mono Winforms 中的第一步
- 布局管理
- 菜單和工具欄
- Mono Winforms 中的基本控件
- Mono Winforms 中的基本控件 II
- Mono Winforms 中的高級控件
- 對話框
- Mono Winforms 中的拖放
- 繪圖
- IronPython Mono Winforms 中的繪圖 II
- IronPython Mono Winforms 中的貪食蛇
- IronPython Mono Winforms 中的俄羅斯方塊游戲
- FreeBASIC GTK 教程
- Jython Swing 教程
- Jython Swing 簡介
- Jython Swing 中的布局管理
- Jython Swing 中的組件
- Jython Swing 中的菜單和工具欄
- Jython Swing 中的對話框
- Jython Swing 中的繪圖
- Jython Swing 中的半字節
- JRuby Swing 教程
- JRuby Swing 簡介
- JRuby Swing 中的布局管理
- JRuby Swing 中的組件
- 菜單和工具欄
- JRuby Swing 中的對話框
- 在 JRuby Swing 中繪圖
- JRuby Swing 中的貪食蛇
- Visual Basic Winforms 教程
- Visual Basic Winforms 簡介
- 布局管理
- 基本控制
- 進階控件
- 菜單和工具欄
- 對話框
- 繪圖
- 拖放
- 貪食蛇
- JavaScript GTK 教程
- JavaScript GTK 簡介
- 布局管理
- JavaScript GTK 中的小部件
- JavaScript GTK 中的菜單和工具欄
- JavaScript GTK 中的對話框
- JavaScript GTK 中的 Cario 繪圖
- ZetCode Java 教程
- Java 教程
- Java 語言
- Java 語法結構
- Java 基礎
- Java 數據類型
- Java 數據類型 II
- Java 字符串
- Java 數組
- Java 表達式
- Java 控制流程
- Java 面向對象的編程
- Java 方法
- Java 面向對象編程 II
- Java 包
- Java 中的異常
- Java 集合
- Java 流
- Java Future 教程
- Java Comparable和Comparator
- Java DOM 教程
- Java MVC 教程
- Java SAX 教程
- Java JAXB 教程
- Java JSON 處理教程
- Java H2 教程
- MongoDB Java 教程
- Java 正則表達式教程
- Java PDFBox 教程
- Java 文件教程
- Java Files.list教程
- Java Files.walk教程
- Java DirectoryStream教程
- Java 外部與內部迭代器
- Java 文件大小
- 用 Java 創建目錄
- 用 Java 創建文件
- Java Log4j 教程
- Gson 教程
- Java RequestDispatcher
- Java HTTP GET/POST 請求
- Java InputStream教程
- Java FileOutputStream教程
- Java FileInputStream教程
- Java ZipInputStream教程
- Java FileWriter教程
- EJB 簡介
- Java forEach教程
- Jetty 教程
- Tomcat Derby 教程
- Stripes 介紹
- 使用 Stripes 的 Java webapp,MyBatis,& Derby
- EclipseLink 簡介
- Java 中的數據源
- JSTL 中的 SQL 查詢標記
- Java 驗證過濾器
- Hibernate 驗證器
- 用 Java 顯示圖像
- Play 框架簡介
- Spark Java 簡介
- Java ResourceBundle教程
- Jtwig 教程
- Java Servlet 教程
- Java 套接字教程
- FreeMarker 教程
- Android 教程
- Java EE 5 教程
- JSoup 教程
- JFreeChart 教程
- ImageIcon教程
- 用 Java 復制文件
- Java 文件時間教程
- 如何使用 Java 獲取當前日期時間
- Java 列出目錄內容
- Java 附加到文件
- Java ArrayList教程
- 用 Java 讀寫 ICO 圖像
- Java int到String的轉換
- Java HashSet教程
- Java HashMap教程
- Java static關鍵字
- Java 中的HashMap迭代
- 用 Java 過濾列表
- 在 Java 中讀取網頁
- Java 控制臺應用
- Java 集合的便利工廠方法
- Google Guava 簡介
- OpenCSV 教程
- 用 Java8 的StringJoiner連接字符串
- Java 中元素迭代的歷史
- Java 謂詞
- Java StringBuilder
- Java 分割字串教學
- Java NumberFormat
- Java TemporalAdjusters教程
- Apache FileUtils教程
- Java Stream 過濾器
- Java 流歸約
- Java 流映射
- Java InputStreamReader教程
- 在 Java 中讀取文本文件
- Java Unix 時間
- Java LocalTime
- Java 斐波那契
- Java ProcessBuilder教程
- Java 11 的新功能
- ZetCode JavaScript 教程
- Ramda 教程
- Lodash 教程
- Collect.js 教程
- Node.js 簡介
- Node HTTP 教程
- Node-config 教程
- Dotenv 教程
- Joi 教程
- Liquid.js 教程
- faker.js 教程
- Handsontable 教程
- PouchDB 教程
- Cheerio 教程
- Axios 教程
- Jest 教程
- JavaScript 正則表達式
- 用 JavaScript 創建對象
- Big.js 教程
- Moment.js 教程
- Day.js 教程
- JavaScript Mustache 教程
- Knex.js 教程
- MongoDB JavaScript 教程
- Sequelize 教程
- Bookshelf.js 教程
- Node Postgres 教程
- Node Sass 教程
- Document.querySelector教程
- Document.all教程
- JSON 服務器教程
- JavaScript 貪食蛇教程
- JavaScript 構建器模式教程
- JavaScript 數組
- XMLHttpRequest教程
- 從 JavaScript 中的 URL 讀取 JSON
- 在 JavaScript 中循環遍歷 JSON 數組
- jQuery 教程
- Google 圖表教程
- ZetCode Kotlin 教程
- Kotlin Hello World 教程
- Kotlin 變量
- Kotlin 的運算符
- Kotlin when表達式
- Kotlin 數組
- Kotlin 范圍
- Kotlin Snake
- Kotlin Swing 教程
- Kotlin 字符串
- Kotlin 列表
- Kotlin 映射
- Kotlin 集合
- Kotlin 控制流程
- Kotlin 寫入文件
- Kotlin 讀取文件教程
- Kotlin 正則表達式
- ZetCode 其它教程
- TCL 教程
- Tcl
- Tcl 語法結構
- Tcl 中的基本命令
- Tcl 中的表達式
- Tcl 中的控制流
- Tcl 中的字符串
- Tcl 列表
- Tcl 中的數組
- Tcl 中的過程
- 輸入&輸出
- AWK 教程
- Vaadin 教程
- Vaadin 框架介紹
- Vaadin Grid教程
- Vaadin TextArea教程
- Vaadin ComboBox教程
- Vaadin Slider教程
- Vaadin CheckBox教程
- Vaadin Button教程
- Vaadin DateField教程
- Vaadin Link教程
- ZetCode PHP 教程
- PHP 教程
- PHP
- PHP 語法結構
- PHP 基礎
- PHP 數據類型
- PHP 字符串
- PHP 運算符
- PHP 中的控制流
- PHP 數組
- PHP 數組函數
- PHP 中的函數
- PHP 正則表達式
- PHP 中的面向對象編程
- PHP 中的面向對象編程 II
- PHP Carbon 教程
- PHP Monolog 教程
- PHP 配置教程
- PHP Faker 教程
- Twig 教程
- Valitron 教程
- Doctrine DBAL QueryBuilder 教程
- PHP Respect 驗證教程
- PHP Rakit 驗證教程
- PHP PDO 教程
- CakePHP 數據庫教程
- PHP SQLite3 教程
- PHP 文件系統函數
- ZetCode Python 教程
- Python 教程
- Python 語言
- 交互式 Python
- Python 語法結構
- Python 數據類型
- Python 字符串
- Python 列表
- Python 字典
- Python 運算符
- Python 關鍵字
- Python 函數
- Python 中的文件
- Python 中的面向對象編程
- Python 模塊
- Python 中的包
- Python 異常
- Python 迭代器和生成器
- Python 內省
- Python Faker 教程
- Python f 字符串教程
- Python bcrypt 教程
- Python 套接字教程
- Python smtplib教程
- OpenPyXL 教程
- Python pathlib教程
- Python YAML 教程
- Python 哈希教程
- Python ConfigParser教程
- Python 日志教程
- Python argparse 教程
- Python SQLite 教程
- Python Cerberus 教程
- Python PostgreSQL 教程
- PyMongo 教程
- PyMySQL 教程
- Peewee 教程
- pyDAL 教程
- pytest 教程
- Bottle 教程
- Python Jinja 教程
- PrettyTable 教程
- BeautifulSoup 教程
- pyquery 教程
- Python for循環
- Python 反轉
- Python Lambda 函數
- Python 集合
- Python 映射
- Python CSV 教程-讀寫 CSV
- Python 正則表達式
- Python SimpleJson 教程
- SymPy 教程
- Pandas 教程
- Matplotlib 教程
- Pillow 教程
- Python FTP 教程
- Python Requests 教程
- Python Arrow 教程
- Python 列表推導式
- Python 魔術方法
- PyQt 中的QPropertyAnimation
- PyQt 中的QNetworkAccessManager
- ZetCode Ruby 教程
- Ruby 教程
- Ruby
- Ruby 語法結構
- Ruby 基礎
- Ruby 變量
- Ruby 中的對象
- Ruby 數據類型
- Ruby 字符串
- Ruby 表達式
- Ruby 控制流
- Ruby 數組
- Ruby 哈希
- Ruby 中的面向對象編程
- Ruby 中的面向對象編程 II
- Ruby 正則表達式
- Ruby 輸入&輸出
- Ruby HTTPClient教程
- Ruby Faraday 教程
- Ruby Net::HTTP教程
- ZetCode Servlet 教程
- 從 Java Servlet 提供純文本
- Java Servlet JSON 教程
- Java Servlet HTTP 標頭
- Java Servlet 復選框教程
- Java servlet 發送圖像教程
- Java Servlet JQuery 列表教程
- Servlet FreeMarker JdbcTemplate 教程-CRUD 操作
- jQuery 自動補全教程
- Java servlet PDF 教程
- servlet 從 WAR 內讀取 CSV 文件
- Java HttpServletMapping
- EasyUI datagrid
- Java Servlet RESTFul 客戶端
- Java Servlet Log4j 教程
- Java Servlet 圖表教程
- Java ServletConfig教程
- Java Servlet 讀取網頁
- 嵌入式 Tomcat
- Java Servlet 分頁
- Java Servlet Weld 教程
- Java Servlet 上傳文件
- Java Servlet 提供 XML
- Java Servlet 教程
- JSTL forEach標簽
- 使用 jsGrid 組件
- ZetCode Spring 教程
- Spring @Bean注解教程
- Spring @Autowired教程
- Spring @GetMapping教程
- Spring @PostMapping教程
- Spring @DeleteMapping教程
- Spring @RequestMapping教程
- Spring @PathVariable教程
- Spring @RequestBody教程
- Spring @RequestHeader教程
- Spring Cookies 教程
- Spring 資源教程
- Spring 重定向教程
- Spring 轉發教程
- Spring ModelAndView教程
- Spring MessageSource教程
- Spring AnnotationConfigApplicationContext
- Spring BeanFactoryPostProcessor教程
- Spring BeanFactory教程
- Spring context:property-placeholder教程
- Spring @PropertySource注解教程
- Spring @ComponentScan教程
- Spring @Configuration教程
- Spring C 命名空間教程
- Spring P 命名空間教程
- Spring bean 引用教程
- Spring @Qualifier注解教程
- Spring ClassPathResource教程
- Spring 原型作用域 bean
- Spring Inject List XML 教程
- Spring 概要文件 XML 教程
- Spring BeanDefinitionBuilder教程
- Spring 單例作用域 bean
- 獨立的 Spring 應用
- 經典 Spring 應用中的JdbcTemplate
- Spring EmbeddedDatabaseBuilder教程
- Spring HikariCP 教程
- Spring Web 應用簡介
- Spring BeanPropertyRowMapper教程
- Spring DefaultServlet教程
- Spring WebSocket 教程
- Spring WebJars 教程
- Spring @MatrixVariable教程
- Spring Jetty 教程
- Spring 自定義 404 錯誤頁面教程
- Spring WebApplicationInitializer教程
- Spring BindingResult教程
- Spring FreeMarker 教程
- Spring Thymeleaf 教程
- Spring ResourceHandlerRegistry教程
- SpringRunner 教程
- Spring MockMvc 教程
- ZetCode Spring Boot 教程
- Spring Boot 發送電子郵件教程
- Spring Boot WebFlux 教程
- Spring Boot ViewControllerRegistry教程
- Spring Boot CommandLineRunner教程
- Spring Boot ApplicationReadyEvent 教程
- Spring Boot CORS 教程
- Spring Boot @Order教程
- Spring Boot @Lazy教程
- Spring Boot Flash 屬性
- Spring Boot CrudRepository 教程
- Spring Boot JpaRepository 教程
- Spring Boot findById 教程
- Spring Boot Data JPA @NamedQuery教程
- Spring Boot Data JPA @Query教程
- Spring Boot Querydsl 教程
- Spring Boot Data JPA 排序教程
- Spring Boot @DataJpaTest教程
- Spring Boot TestEntityManager 教程
- Spring Boot Data JPA 派生的查詢
- Spring Boot Data JPA 查詢示例
- Spring Boot Jersey 教程
- Spring Boot CSV 教程
- SpringBootServletInitializer教程
- 在 Spring Boot 中加載資源
- Spring Boot H2 REST 教程
- Spring Boot RestTemplate
- Spring Boot REST XML 教程
- Spring Boot Moustache 教程
- Spring Boot Thymeleaf 配置
- Spring Boot 自動控制器
- Spring Boot FreeMarker 教程
- Spring Boot Environment
- Spring Boot Swing 集成教程
- 在 Spring Boot 中提供圖像文件
- 在 Spring Boot 中創建 PDF 報告
- Spring Boot 基本注解
- Spring Boot @ResponseBody教程
- Spring Boot @PathVariable教程
- Spring Boot REST Data JPA 教程
- Spring Boot @RequestParam教程
- Spring Boot 列出 bean
- Spring Boot @Bean
- Spring Boot @Qualifier教程
- 在 Spring Boot 中提供靜態內容
- Spring Boot Whitelabel 錯誤
- Spring Boot DataSourceBuilder 教程
- Spring Boot H2 教程
- Spring Boot Web JasperReports 集成
- Spring Boot iText 教程
- Spring Boot cmd JasperReports 集成
- Spring Boot RESTFul 應用
- Spring Boot 第一個 Web 應用
- Spring Boot Groovy CLI
- Spring Boot 上傳文件
- Spring Boot @ExceptionHandler
- Spring Boot @ResponseStatus
- Spring Boot ResponseEntity
- Spring Boot @Controller
- Spring Boot @RestController
- Spring Boot @PostConstruct
- Spring Boot @Component
- Spring Boot @ConfigurationProperties教程
- Spring Boot @Repository
- Spring Boot MongoDB 教程
- Spring Boot MongoDB Reactor 教程
- Spring Boot PostgreSQL 教程
- Spring Boot @ModelAttribute
- Spring Boot 提交表單教程
- Spring Boot Model
- Spring Boot MySQL 教程
- Spring Boot GenericApplicationContext
- SpringApplicationBuilder教程
- Spring Boot Undertow 教程
- Spring Boot 登錄頁面教程
- Spring Boot RouterFunction 教程
- ZetCode Symfony 教程
- Symfony DBAL 教程
- Symfony 表單教程
- Symfony CSRF 教程
- Symfony Vue 教程
- Symfony 簡介
- Symfony 請求教程
- Symfony HttpClient教程
- Symfony Flash 消息
- 在 Symfony 中發送郵件
- Symfony 保留表單值
- Symfony @Route注解教程
- Symfony 創建路由
- Symfony 控制臺命令教程
- Symfony 上傳文件
- Symfony 服務教程
- Symfony 驗證教程
- Symfony 翻譯教程