# SQLite Python 教程
> 原文: [http://zetcode.com/db/sqlitepythontutorial/](http://zetcode.com/db/sqlitepythontutorial/)
该教程已被 [Python SQLite 教程](/python/sqlite)取代。
这是用于 SQLite 数据库的 Python 编程教程。 它涵盖了使用 Python 语言进行 SQLite 编程的基础。 您可能还需要查看 ZetCode 上的 [Python 教程](/lang/python/), [SQLite 教程](/db/sqlite/)或 [MySQL Python 教程](/db/mysqlpython/)或 [PostgreSQL Python 教程](/db/postgresqlpythontutorial/)。
要使用本教程,我们必须在系统上安装 Python 语言,SQLite 数据库,`pysqlite`语言绑定和`sqlite3`命令行工具。
[Tweet](https://twitter.com/share)
如果我们拥有 Python 2.5+,则只需安装`sqlite3`命令行工具。 SQLite 库和`pysqlite`语言绑定都内置在 Python 语言中。
```py
$ python2
Python 2.7.12 (default, Nov 12 2018, 14:36:49)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.version
'2.6.0'
>>> sqlite3.sqlite_version
'3.16.2'
```
在外壳程序中,我们启动 Python 交互式解释器。 我们可以看到 Python 版本。 在我们的例子中是 Python 2.7.12。 `sqlite.version`是`pysqlite`(2.6.0)的版本,它是 Python 语言与 SQLite 数据库的绑定。 `sqlite3.sqlite_version`为我们提供了 SQLite 数据库库的版本。 在我们的例子中,版本是 3.16.2。
## SQLite
SQLite 是嵌入式关系数据库引擎。 该文档称其为自包含,无服务器,零配置和事务型 SQL 数据库引擎。 它非常受欢迎,当今全球有数亿本使用。 几种编程语言都内置了对 SQLite 的支持,包括 Python 和 PHP。
## 创建 SQLite 数据库
现在,我们将使用`sqlite3`命令行工具创建一个新数据库。
```py
$ sqlite3 test.db
SQLite version 3.16.2 2017-01-06 16:32:41
Enter ".help" for usage hints.
sqlite>
```
我们为`sqlite3 tool`提供了一个参数; `test.db`是数据库名称。 这是我们磁盘上的文件。 如果存在,则将其打开。 如果不是,则创建它。
```py
sqlite> .tables
sqlite> .exit
$ ls
test.db
```
`.tables`命令提供了`test.db`数据库中的表列表。 当前没有表。 `.exit`命令终止 sqlite3 命令行工具的交互式会话。 `ls` Unix 命令显示当前工作目录的内容。 我们可以看到`test.db`文件。 所有数据将存储在该单个文件中。
## SQLite 版本示例
在第一个代码示例中,我们将获得 SQLite 数据库的版本。
`version.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
con = None
try:
con = lite.connect('test.db')
cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')
data = cur.fetchone()[0]
print "SQLite version: {}".format(data)
except lite.Error, e:
print "Error {}:".format(e.args[0])
sys.exit(1)
finally:
if con:
con.close()
```
在上面的 Python 脚本中,我们连接到先前创建的`test.db`数据库。 我们执行一条 SQL 语句,该语句返回 SQLite 数据库的版本。
```py
import sqlite3 as lite
```
`sqlite3`模块用于处理 SQLite 数据库。
```py
con = None
```
我们将`con`变量初始化为无。 如果无法创建与数据库的连接(例如磁盘已满),则不会定义连接变量。 这将导致`finally`子句中的错误。
```py
con = lite.connect('test.db')
```
在这里,我们连接到`test.db`数据库。 `connect()`方法返回一个连接对象。
```py
cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')
```
从连接中,我们得到光标对象。 游标用于遍历结果集中的记录。 我们调用游标的`execute()`方法并执行 SQL 语句。
```py
data = cur.fetchone()[0]
```
我们获取数据。 由于只检索一条记录,因此我们称为`fetchone()`方法。
```py
print "SQLite version: {}".format(data)
```
我们将检索到的数据打印到控制台。
```py
except lite.Error, e:
print "Error {}:".format(e.args[0])
sys.exit(1)
```
如果发生异常,我们将输出一条错误消息,并以错误代码 1 退出脚本。
```py
finally:
if con:
con.close()
```
在最后一步,我们释放资源。
在第二个示例中,我们再次获得 SQLite 数据库的版本。 这次我们将使用`with`关键字。
`version2.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')
data = cur.fetchone()[0]
print "SQLite version: {}".format(data)
```
该脚本返回 SQLite 数据库的当前版本。 通过使用`with`关键字。 代码更紧凑。
```py
with con:
```
使用`with`关键字,Python 解释器会自动释放资源。 它还提供错误处理。
```py
$ ./version2.py
SQLite version: 3.16.2
```
这是输出。
## SQLite Python 创建表
我们创建一个`cars`表并在其中插入几行。
`create_table.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.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`表的数据。
我们将创建相同的表。 这次使用便捷的`executemany()`方法。
`create_table2.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
cars = (
(1, 'Audi', 52642),
(2, 'Mercedes', 57127),
(3, 'Skoda', 9000),
(4, 'Volvo', 29000),
(5, 'Bentley', 350000),
(6, 'Hummer', 41400),
(7, 'Volkswagen', 21600)
)
con = lite.connect('test.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 语句。 第二个参数是数据,以元组的元组的形式。
我们提供了另一种创建`cars`表的方法。 我们手动提交更改并提供我们自己的错误处理。
`create_table3.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
try:
con = lite.connect('test.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 lite.Error, e:
if con:
con.rollback()
print "Error {}:".format(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 lite.Error, e:
if con:
con.rollback()
print "Error {}:".format(e.args[0])
sys.exit(1)
```
发生错误时,所做的更改将回滚,并在终端上显示一条错误消息。
## SQLite Python lastrowid
有时,我们需要确定最后插入的行的 ID。 在 Python SQLite 中,我们使用光标对象的`lastrowid`属性。
`lastrowid.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.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 "The last Id of the inserted row is {}".format(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
```
我们看到了程序的输出。
## SQLite Python 检索数据
现在我们已经将一些数据插入数据库中,我们想要取回它。
`select_all.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute("SELECT * FROM cars")
rows = cur.fetchall()
for row in rows:
print row
```
在此示例中,我们从`cars`表中检索所有数据。
```py
cur.execute("SELECT * FROM cars")
```
该 SQL 语句从`cars`表中选择所有数据。
```py
rows = cur.fetchall()
```
`fetchall()`方法获取所有记录。 它返回一个结果集。 从技术上讲,它是一个元组的元组。 每个内部元组代表表中的一行。
```py
for row in rows:
print row
```
我们将数据逐行打印到控制台。
```py
$ ./select_all.py
(1, u'Audi', 52642)
(2, u'Mercedes', 57127)
(3, u'Skoda', 9000)
(4, u'Volvo', 29000)
(5, u'Bentley', 350000)
(6, u'Citroen', 21000)
(7, u'Hummer', 41400)
(8, u'Volkswagen', 21600)
```
这是示例的输出。
一次返回所有数据可能不可行。 我们可以一一读取行。
`fetch_one.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute("SELECT * FROM cars")
while True:
row = cur.fetchone()
if row == None:
break
print row[0], row[1], row[2]
```
在此脚本中,我们连接到数据库,并逐个读取`cars`表的行。
```py
while True:
```
我们从`while`循环访问数据。 当我们读取最后一行时,循环终止。
```py
row = cur.fetchone()
if row == None:
break
```
`fetchone()`方法返回表的下一行。 如果没有剩余数据,则返回`None`。 在这种情况下,我们打破了循环。
```py
print 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
```
这是示例的输出。
## SQLite Python 字典游标
默认游标以元组的元组返回数据。 当我们使用字典游标时,数据以 Python 字典的形式发送。 这样,我们可以通过列名称来引用数据。
`dictionary_cursor.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.db')
with con:
con.row_factory = lite.Row
cur = con.cursor()
cur.execute("SELECT * FROM cars")
rows = cur.fetchall()
for row in rows:
print "{} {} {}".format(row["id"], row["name"], row["price"])
```
在此示例中,我们使用字典光标打印`cars`表的内容。
```py
con.row_factory = lite.Row
```
我们选择一个字典光标。 现在,我们可以按列名访问记录。
```py
for row in rows:
print "{} {} {}".format(row["id"], row["name"], row["price"])
```
通过列名访问数据。
## SQLite Python 参数化查询
现在,我们将关注参数化查询。 当使用参数化查询时,我们使用占位符,而不是直接将值写入语句。 参数化查询可提高安全性和性能。
Python `sqlite3`模块支持两种类型的占位符:问号和命名占位符。
`parameterized_query.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
uId = 1
uPrice = 62300
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute("UPDATE cars SET price=? WHERE id=?", (uPrice, uId))
print "Number of rows updated: {}".format(cur.rowcount)
```
我们更新了一辆车的价格。 在此代码示例中,我们使用问号占位符。
```py
cur.execute("UPDATE cars SET price=? WHERE id=?", (uPrice, uId))
```
问号`?`是值的占位符。 这些值将添加到占位符。
```py
print "Number of rows updated: {}".format(cur.rowcount)
```
`rowcount`属性返回更新的行数。 在我们的情况下,一行已更新。
第二个示例使用带有命名占位符的参数化语句。
`parameterized_query2.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
uId = 4
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute("SELECT name, price FROM cars WHERE Id=:Id", {"Id": uId})
row = cur.fetchone()
print row[0], row[1]
```
我们使用命名的占位符选择汽车的名称和价格。
```py
cur.execute("SELECT name, price FROM cars WHERE Id=:Id", {"Id": uId})
```
命名的占位符以冒号开头。
## SQLite Python 插入图像
在本节中,我们将图像插入到 SQLite 数据库中。 请注意,有些人反对将图像放入数据库。 在这里,我们只展示如何做。 我们不讨论是否将图像保存在数据库中的技术问题。
```py
sqlite> CREATE TABLE images(id INTEGER PRIMARY KEY, data BLOB);
```
对于此示例,我们创建一个名为`Images`的新表。 对于图像,我们使用`BLOB`数据类型,表示二进制大型对象。
`insert_image.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
def readImage():
fin = None
try:
fin = open("sid.png", "rb")
img = fin.read()
return img
except IOError, e:
print e
sys.exit(1)
finally:
if fin:
fin.close()
try:
con = lite.connect('test.db')
cur = con.cursor()
data = readImage()
binary = lite.Binary(data)
cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )
con.commit()
except lite.Error, e:
if con:
con.rollback()
print e
sys.exit(1)
finally:
if con:
con.close()
```
在此脚本中,我们从当前工作目录中读取图像,并将其写入 SQLite `test.db`数据库的`images`表中。
```py
try:
fin = open("sid.png", "rb")
img = fin.read()
return img
```
我们从文件系统读取二进制数据。 我们有一个名为`sid.png`的 JPG 图像。
```py
binary = lite.Binary(data)
```
使用 SQLite `Binary`对象对数据进行编码。
```py
cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )
```
该 SQL 语句用于将映像插入数据库。
## SQLite Python 读取图像
在本节中,我们将执行相反的操作:我们从数据库表中读取一个图像。
`read_image.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
def writeImage(data):
fout = None
try:
fout = open('sid2.png','wb')
fout.write(data)
except IOError, e:
print e
sys.exit(1)
finally:
if fout:
fout.close()
try:
con = lite.connect('test.db')
cur = con.cursor()
cur.execute("SELECT data FROM images LIMIT 1")
data = cur.fetchone()[0]
writeImage(data)
except lite.Error, 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`表中选择并获取数据。 我们从第一行获取二进制数据。
## SQLite Python 元数据
元数据是有关数据库中数据的信息。 SQLite 中的元数据包含有关表和列的信息,我们在其中存储数据。 受 SQL 语句影响的行数是元数据。 结果集中返回的行数和列数也属于元数据。
可以使用`PRAGMA`命令获取 SQLite 中的元数据。 SQLite 对象可能具有属性,即元数据。 最后,我们还可以通过查询 SQLite 系统`sqlite_master`表来获取特定的元数据。
`column_names.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute('PRAGMA table_info(cars)')
data = cur.fetchall()
for d in data:
print 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 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 python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute('SELECT * FROM cars')
col_names = [cn[0] for cn in cur.description]
rows = cur.fetchall()
print "{:3} {:10} {:7}".format(col_names[0], col_names[1], col_names[2])
for row in rows:
print "{:<3} {:<10} {:7}".format(row[0], row[1], row[2])
```
我们将`cars`表的内容打印到控制台。 现在,我们也包括列的名称。 记录与列名对齐。
```py
col_names = [cn[0] for cn in cur.description]
```
我们从游标对象的`description`属性获得列名。
```py
print "{:3} {:10} {:7}".format(col_names[0], col_names[1], col_names[2])
```
此行打印`cars`表的三个列名。
```py
for row in rows:
print "{:<3} {:<10} {:7}".format(row[0], row[1], row[2])
```
我们使用`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
```
这是输出。
在与元数据有关的最后一个示例中,我们将列出`test.db`数据库中的所有表。
`list_tables.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
con = lite.connect('test.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
```
这些是我们系统上的表。
## SQLite Python 数据导出&导入
我们可以转储 SQL 格式的数据以创建数据库表的简单备份。
`export_table.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
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 = lite.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 = lite.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;
```
废弃的内存车表中的内容。
现在,我们将执行反向操作。 我们将转储的表导入回内存。
`import_table.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
def readData():
f = open('cars.sql', 'r')
with f:
data = f.read()
return data
con = lite.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 语句的影响可以全部提交给数据库,也可以全部回滚。
在 SQLite 中,除`SELECT`以外的任何命令都将启动隐式事务。 同样,在事务中,诸如`CREATE TABLE` ...,`VACUUM`和`PRAGMA`之类的命令将在执行之前提交先前的更改。
手动事务以`BEGIN TRANSACTION`语句开始,并以`COMMIT`或`ROLLBACK`语句结束。
SQLite 支持三种非标准事务级别:`DEFERRED`,`IMMEDIATE`和`EXCLUSIVE`。 SQLite Python 模块还支持自动提交模式,该模式下对表的所有更改均立即生效。
`no_commit.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
try:
con = lite.connect('test.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 lite.Error, 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>
```
表已创建,但数据未写入表中。
在第二个示例中,我们演示了一些命令将先前的更改隐式提交到数据库。
`implicit_commit.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
try:
con = lite.connect('test.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')")
cur.execute("CREATE TABLE IF NOT EXISTS temporary(id INT)")
except lite.Error, e:
if con:
con.rollback()
print e
sys.exit(1)
finally:
if con:
con.close()
```
同样,我们没有显式调用`commit()`命令。 但是这一次,数据被写入了`Friends`表。
```py
cur.execute("CREATE TABLE IF NOT EXISTS temporary(id INT)")
```
该 SQL 语句创建一个新表。 它还会提交以前的更改。
```py
$ ./implicit_commit.py
sqlite> SELECT * FROM friends;
id name
---------- ----------
1 Tom
2 Rebecca
3 Jim
4 Robert
```
数据已写入`friends`表。
在自动提交模式下,将立即执行一条 SQL 语句。
`autocommit.py`
```py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
try:
con = lite.connect('test.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 lite.Error, e:
print e
sys.exit(1)
finally:
if con:
con.close()
```
在此示例中,我们以自动提交模式连接到数据库。
```py
con = lite.connect('test.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`表。
这是 SQLite Python 教程。 ZetCode 拥有用于 SQLite Python 的完整电子书:
[SQLite Python 电子书](/ebooks/sqlitepython/)。
- 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 翻译教程