Python 《SQLite教程》

目录

http://zetcode.com/python/sqlite/

Python SQLite教程

SQLite

创建SQLite数据库

Python SQLite版本示例

Python SQLite执行

Python SQLite executemany

Python SQLite执行脚本

Python SQLite lastrowid

Python SQLite使用fetchall检索数据

Python SQLite fetchone

Python SQLite dictionary cursor

Python SQLite parameterized statements

带有问号的参数化语句

带有命名占位符的参数化语句

Python SQLite插入图像

Python SQLite读取图像

Python SQLite元数据

Python SQLite数据导出

Python SQLite导入数据

Python SQLite事务

Python SQLite自动提交


Python SQLite教程

这是SQLite数据库的Python编程教程。它涵盖了使用Python语言编写SQLite的基础知识。ZetCode拥有完整的 电子书为Python SQLite的:Python的SQLite的电子书

要使用本教程,我们必须在系统上安装Python语言,SQLite数据库, pysqlite语言绑定和sqlite3命令行工具。

为了使用SQLite数据库,我们可以安装sqlite3 或SQLite浏览器GUI。

$ 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'

在shell中,我们启动了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命令行工具创建一个新数据库。

$ sqlite3 ydb.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite>

我们提供参数sqlite3 toolydb.db是数据库名称。它是我们磁盘上的一个文件。如果存在,则打开。如果没有,则创建它。

sqlite> .tables
sqlite> .exit
$ ls
ydb.db

.tables命令提供ydb.db 数据库中的表列表。目前没有表格。该.exit命令终止sqlite3命令行工具的交互式会话。在lsUnix命令显示当前工作目录的内容。我们可以看到该ydb.db文件。所有数据都将存储在此单个文件中。

Python SQLite版本示例

在第一个代码示例中,我们将获得SQLite数据库的版本。

#!/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数据库。我们执行一个返回SQLite数据库版本的SQL语句。

import sqlite3 as sqlite

我们导入sqlite3并给它一个别名。

con = None

我们将con变量初始化为None。如果我们无法创建与数据库的连接(例如磁盘已满),我们就不会定义连接变量。这将导致finally子句中的错误。

con = sqlite.connect('ydb.db')

我们连接到ydb.db数据库。该connect() 方法返回一个连接对象。

cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')

从连接中,我们得到了游标对象。游标用于遍历结果集中的记录。我们调用execute()游标的方法并执行SQL语句。

data = cur.fetchone()[0]

我们获取数据。由于我们只检索一条记录,因此我们调用该 fetchone()方法。

print(f"SQLite version: {data}")

我们将检索到的数据打印到控制台。

except sqlite.Error as e:

    print(f"Error {e.args[0]}")
    sys.exit(1)

如果发生异常,我们会打印一条错误消息并退出脚本,错误代码为1。

finally:

    if con:
        con.close()

在最后一步中,我们释放资源。

在第二个示例中,我们再次获取SQLite数据库的版本。这次我们将使用with关键字。

#!/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关键字。代码更紧凑。

with con:

使用with关键字,Python解释器会自动释放资源。它还提供错误处理。

$ ./version.py
SQLite version: 3.21.0

这是输出。

Python SQLite执行

我们创建一个cars表并向其插入几行。我们用execute()

#!/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行。

cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")

此SQL语句创建一个新cars表。该表有三列。

cur.execute("INSERT INTO cars VALUES(1,'Audi',52642)")
cur.execute("INSERT INTO cars VALUES(2,'Mercedes',57127)")

这两条线将两辆车插入桌子。使用该with 关键字,将自动提交更改。否则,我们必须手动提交它们。

sqlite> .mode column
sqlite> .headers on

我们使用该sqlite3工具验证书面数据。首先,我们修改数据在控制台中的显示方式。我们使用列模式并打开标题。

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()方法。

#!/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如果表存在, 程序将删除该表并重新创建它。

cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")

如果存在,则第一个SQL语句将删除cars表。第二个SQL语句创建cars表。

cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)

我们使用便捷executemany()方法在表中插入8行。此方法的第一个参数是参数化SQL语句。第二个参数是元组元组形式的数据。

Python SQLite执行脚本

我们提供了另一种创建cars表的方法executescript()。我们手动提交更改并提供自己的错误处理。

#!/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()

在上面的脚本中,我们(重新)cars使用该executescript()方法创建表 。

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代码。

con.commit()

如果没有with关键字,则必须使用该commit()方法提交更改。

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游标对象的属性。

#!/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自动递增。

cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT);")

在SQLite中,INTEGER PRIMARY KEY列自动递增。还有一个AUTOINCREMENT关键字。当使用INTEGER PRIMARY KEY AUTOINCREMENT略微不同的算法进行Id创建时。

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表中插入四行。

last_row_id = cur.lastrowid

使用lastrowid我们获取最后插入的行ID。

$ ./lastrowid.py
The last Id of the inserted row is 4

我们看到了该计划的输出。

Python SQLite使用fetchall检索数据

fetchall()方法获取查询结果集的所有(或所有剩余)行,并返回元组列表。

#!/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表中检索所有数据。

cur.execute("SELECT * FROM cars")

此SQL语句选择cars表中的所有数据。

rows = cur.fetchall()

fetchall()方法获取所有记录。它返回一个结果集。从技术上讲,它是元组的元组。每个内部元组表示表中的一行。

for row in rows:
    print(f"{row[0]} {row[1]} {row[2]}")

我们逐行将数据打印到控制台。

$ ./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时,没有更多的数据是可用的。

#!/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逐个获取表的行。

while True:

我们从while循环访问数据。当我们读取最后一行时,循环终止。

row = cur.fetchone()

if row == None:
    break

fetchone()方法返回表中的下一行。如果没有剩余数据,则返回None。在这种情况下,我们打破了循环。

print(f"{row[0]} {row[1]} {row[2]}")

数据以元组的形式返回。在这里,我们从元组中选择记录。第一个是Id,第二个是汽车名称,第三个是汽车的价格。

$ ./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 dictionary cursor

默认光标返回元组元组中的数据。当我们使用字典光标时,数据以Python字典的形式发送。这样我们就可以通过列名来引用数据。

!/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使用字典光标打印表的内容。

con.row_factory = sqlite.Row

我们选择一个字典光标。现在我们可以按列的名称访问记录。

for row in rows:
    print(f"{row['id']} {row['name']} {row['price']}")

列名称访问数据。

Python SQLite parameterized statements

现在我们将关注参数化查询。当我们使用参数化查询时,我们使用占位符而不是直接将值写入语句。参数化查询可提高安全性和性能。

Python sqlite3模块支持两种类型的占位符:问号和命名占位符。

带有问号的参数化语句

在第一个例子中,我们使用问号的语法

#!/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}")

我们更新一辆车的价格。在此代码示例中,我们使用问号占位符。

cur.execute("UPDATE cars SET price=? WHERE id=?", (uPrice, uId))

问号?是价值的占位符。这些值将添加到占位符中。

print(f"Number of rows updated: {cur.rowcount}")

rowcount属性返回更新的行数。在我们的例子中,一行已更新。

带有命名占位符的参数化语句

第二个示例使用带有命名占位符的参数化语句。

#!/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]}")

我们使用命名占位符选择汽车的名称和价格。

cur.execute("SELECT name, price FROM cars WHERE Id=:Id", {"Id": uId})

命名占位符以冒号字符开头。

Python SQLite插入图像

在本节中,我们将向SQLite数据库插入一个图像。请注意,有些人反对将图像放入数据库。这里我们只展示如何做到这一点。我们不会讨论是否在数据库中保存图像的技术问题。

sqlite> CREATE TABLE images(id INTEGER PRIMARY KEY, data BLOB);

在本例中,我们创建了一个名为Images的新表。对于图像,我们使用BLOB数据类型,它代表二进制大对象。

#!/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()

在此脚本中,我们从当前工作目录中读取图像并将其写入imagesSQLite ydb.db数据库的表中 。

try:
    fin = open("sid.png", "rb")
    img = fin.read()
    return img

我们从文件系统中读取二进制数据。我们有一个名为的JPG图像sid.png

binary = sqlite.Binary(data)

使用SQLite Binary对象对数据进行编码。

cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )

此SQL语句用于将映像插入数据库。

Python SQLite读取图像

在本节中,我们将执行相反的操作:我们从数据库表中读取图像。

#!/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

try:
    fout = open('sid2.png','wb')
    fout.write(data)

我们以书写模式打开二进制文件。数据库中的数据将写入文件。

cur.execute("SELECT data FROM images LIMIT 1")
data = cur.fetchone()[0]

这两行选择并从images 表中获取数据。我们从第一行获取二进制数据。

Python SQLite元数据

元数据是有关数据库中数据的信息。SQLite中的元数据包含有关表和列的信息,我们在其中存储数据。受SQL语句影响的行数是元数据。结果集中返回的行数和列数也属于元数据。

可以使用该PRAGMA命令获取SQLite中的元数据。SQLite对象可能具有属性,即元数据。最后,我们还可以从查询SQLite系统sqlite_master表中获取特定的元数据 。

#!/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表的一些元数据信息。

cur.execute('PRAGMA table_info(cars)')

PRAGMA table_info(tableName)命令为cars表中的每列返回一行。结果集中的列包括列顺序号,列名,数据类型,列是否可以NULL以及列 的默认值。

for d in data:
    print(f"{d[0]} {d[1]} {d[2]}")

从提供的信息中,我们打印列订单号,列名和列数据类型。

$ ./column_names.py
0 id INT
1 name TEXT
2 price INT

这是示例的输出。

在下面的示例中,我们cars使用列名来打印表中的所有行。

#!/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表的内容打印到控制台。现在,我们也包括列的名称。记录与列名称对齐。

col_names = [cn[0] for cn in cur.description]

我们从description游标对象的属性中获取列名。

print(f"{col_names[0]:3} {col_names[1]:10} {col_names[2]:7}")

此行打印cars表的三个列名称。

for row in rows:
    print(f"{row[0]:<3} {row[1]:<10} {row[2]:7}")

我们使用for循环打印行。数据与列名对齐。

$  ./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数据库中的所有表。

#!/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])

代码示例将当前数据库中的所有可用表打印到终端。

cur.execute("SELECT name FROM sqlite_master WHERE type='table'")

表名存储在系统sqlite_master表中。

$ ./list_tables.py
cars
images

这些是我们系统上的表格。

Python SQLite数据导出

我们可以以SQL格式转储数据,以创建数据库表的简单备份。

#!/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文件中。此文件可用作表的当前备份。

def writeData(data):

    f = open('cars.sql', 'w')

    with f:
        f.write(data)

表中的数据正被写入文件。

con = sqlite.connect(':memory:')

我们在内存中创建一个临时表。

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个单位。

data = '\n'.join(con.iterdump())

con.iterdump()返回迭代倾倒在SQL文本格式的数据库。内置join() 函数接受迭代器并连接迭代器中由新行分隔的所有字符串。此数据将写入writeData()函数中的cars.sql文件。

$ 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导入数据

现在我们将执行反向操作。我们将转储的表重新导入内存。

#!/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文件的内容并执行它。这将重新创建转储表。

def readData():

    f = open('cars.sql', 'r')

    with f:
    
        data = f.read()
        
        return data

readData()方法内部,我们读取了cars.sql表的内容。

cur.executescript(sql)

我们调用该executescript()方法来启动SQL脚本。

cur.execute("SELECT * FROM cars")

rows = cur.fetchall()

for row in rows:
    print(row)

我们验证数据。

$ ./import_table.py
(1, u'Audi', 52643)
(2, u'Mercedes', 57642)
(5, u'Bentley', 350000)
(6, u'Hummer', 41400)

输出显示我们已成功重新创建已保存的汽车表。

Python SQLite事务

事务是针对一个或多个数据库中的数据的数据库操作的原子单元。事务中所有SQL语句的影响可以全部提交到数据库,也可以全部回滚。

sqlite3默认情况下,Python 模块BEGIN在数据修改语言(DML)语句(即INSERTUPDATE/DELETEREPLACE)之前隐式发出语句。

sqlite3使用DDL语句之前隐式提交打开的事务。这已不再是这种情况。

手动事务从BEGIN TRANSACTION语句开始,并以COMMITROLLBACK语句结束。

SQLite支持三无标准的交易水平:DEFERRED, IMMEDIATEEXCLUSIVE。Python SQLite模块还支持自动提交模式,其中对表的所有更改都立即生效。

#!/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表并尝试用数据填充它。但是,正如我们将看到的,数据未提交。

#con.commit()

commit()方法被评论。如果我们取消注释该行,数据将被写入表中。

sqlite> .tables
cars     friends  images 
sqlite> SELECT Count(id) FROM friends;
Count(id) 
----------
0         
sqlite>

表已创建,但数据未写入表。

Python SQLite自动提交

在自动提交模式下,立即执行SQL语句。

#!/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()

在此示例中,我们以自动提交模式连接到数据库。

con = sqlite.connect('ydb.db', isolation_level=None)

我们将自动提交模式设置isolation_level为无。

$ ./autocommit.py

sqlite> SELECT * FROM friends;
Id          Name
----------  ----------
1           Tom
2           Rebecca
3           Jim
4           Robert

数据已成功提交到friends表中。

发布了59 篇原创文章 · 获赞 69 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/pansaky/article/details/99674449
今日推荐