Python SQLite 数据库插入 Tips

SQLite 是一款常用、轻量的数据库。虽然使用比较简单易懂,但也存在一些小技巧。本文将介绍 SQLite 中 Python 应用的Tips。

首先,在 Python 使用 SQLite 要先安装 sqlite3 库的依赖:


conda install sqlite3

pip install sqlite3

然后需要在程序的开头应用库:

import sqlite3

在开始介绍 Tips 之前,先来创建一个数据表:


db = sqlite3.connect('database/py-sqlite-inster-tips.db')

接下来,为演示创建一个 Person 的数据表:


create_sql = '''
    CREATE TABLE "Person" (
        "id" INTEGER NOT NULL UNIQUE,
        "name" TEXT NOT NULL,
        "age" INTEGER NOT NULL DEFAULT 18,
        PRIMARY KEY("id" AUTOINCREMENT)
);
'''

db.execute(create_sql)

select_table_name_sql = 'SELECT name FROM sqlite_master WHERE type = "table";'

cursor = db.cursor()

cursor.execute(select_table_name_sql)

print(cursor.fetchall())
>>
[('Person',), ('sqlite_sequence',)]

这样,我们就已经成功创建了演示用的 Person 数据表了。

sqlite3 使用游标 cursorexecute 可以执行 SQL 语句。在 SQLite 中,插入数据语法如下:

INSERT INTO  VALUES (value1, value2...);

我们尝试插入一条记录:

insert_sql = 'INSERT INTO Person VALUES (1, 'persion 1', 20)'
cursor.execute(insert_sql)

query_sql = 'SELECT * FROM Person;'
cursor.execute(quert_sql)

print(cursor.fetchall())
>>
[(1, 'person-1', 20)]

这里就可以看到我们已经向表中添加了一条记录。这里要注意一点,上面的代码插入一行记录,并且我们使用查询语句也可以查询到我们添加的记录,但是我们的插入到现在为止并没有提交。可以尝试去查看一下数据库目录,可以看到下面会多了一个文件 py-sqlite-inster-tips.db-journal,这时,如果我们使用另外一个程序(GUI工具 – DB Browser 或者使用另外一个python程序)打开 py-sqlite-inster-tips.db ,会发现里面并没有我们刚刚添加的记录。
所以我们需要执行一下提交。


db.commit()

这时,我们可以发现,刚刚的 db-journal 文件不见了,我们使用其他工具再打开数据库,也是可以看到新的记录。

接下来,我们再尝试插入另外一条新的记录。

insert_person_2_sql = 'INSERT INTO Person VALUES (1, "person 2", 21);'
cursor.execute('insert_person_2_sql')
>>
......

IntegrityError: UNIQUE constraint failed: Person.id

可以看到,程序出现了报错。这是因为我们在创建表的时候,给 id 字段添加了唯一的约束。现在的 Person 表中,已经存在 id 为 1 的字段,因此如果再向数据表中添加 id 的 1 的数据记录,就会报错。
解决办法也很简单,我们使用一个没有在数据表中占用的 id 即可。

insert_person_2_sql = 'INSERT INTO Person VALUES (2, "person 2", 21);'
cursor.execute('insert_person_2_sql')

cursor.execute(quert_sql)
print(cursor.fetchall())
>>
[(1, 'person-1', 20), (2, 'persopn 2', 21)]

我们的 id 字段,除了唯一约束,还有自增属性。我们为 Person 表再添加一个记录。

insert_person_10_sql = 'INSERT INTO Person VALUES (10, "person 10", 30);'
cursor.execute('insert_person_10_sql')

cursor.execute(quert_sql)
print(cursor.fetchall())
>>
[(1, 'person-1', 20), (2, 'persopn 2', 21), (10, 'person 10', 30)]

然后,我们在上面 Person 表中有三个记录的基础上,在添加一个记录,这一次,我们不在指定 id 。

insert_person_3_sql = 'INSERT INTO Person VALUES (NULL, "person 3", 18);'
cursor.execute('insert_person_10_sql')

cursor.execute(quert_sql)
print(cursor.fetchall())
>>
[(1, 'person-1', 20), (2, 'persopn 2', 21), (10, 'person 10', 30), (11, 'person 3', 18)]

可以看到,最后添加的字段,它的 id 是在上一条记录之上加 1 ,变成 11,而数据表中,3~9 的 id 就会没有。我们在设计表的时候,设置 id 字段为唯一及自增,通常是想让 id 字段自己按顺序增长,但因为我们上面指定 id 的操作,会让我们的数据记录没有像我们预期般存储。
解决的办法也很简单,我们可以不对 id 进行指定,使用 NULL 让数据库自己处理,又或者我们指定我们需要插入的数据字段:

insert_person_sql = 'INSERT INTO Person (name, age) VALUES (?, ?);'
cursor.execute(insert_person_sql, ('person_12', 33))

cursor.execute(quert_sql)
print(cursor.fetchall())
>>
[(1, 'person-1', 20), (2, 'persopn 2', 21), (10, 'person 10', 30), (11, 'person 3', 18), (12, 'person_12', 33)]

在上面的例子中,我们在 SQL 语句中使用了 ? 来替代真实需要插入的数据。但是这里会有一个问题,可以看一下下面的代码:

insert_person_single_sql = 'INSERT INTO PERSON (name) VALUES (?);'
cursor.execute(insert_person_single_sql, 'person 13')
>>
......

ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 10 supplied.

可以看到,我们如果将 name 字段的内容直接作为参数,会出现报错。报错提示我们的参数个数不对。
接下来,我们对代码进行修改:

cursor.execute(insert_person_single_sql, ('person 13',))

cursor.execute(quert_sql)
print(cursor.fetchall())
>>
[(1, 'person-1', 20), (2, 'persopn 2', 21), (10, 'person 10', 30), (11, 'person 3', 18), (12, 'person_12', 33), (13, 'person', 18)]

这样,就可以正常插入了。为什么我们需要构造一个元组才能成功执行代码呢?来看一下下面代码:

len('person 10')
>>
10
type('person 10')
>>
str
len(('person 10', ))
>>
1
type(('person 10', ))
>>
tuple

我们知道 SQL 语句需要接收一个数据,我们可以从上面的代码知道,如果只传入我们需要存储的数据(作为str),它的长度是10,而当我们将数据作为一个元组成为参数,这里的长度是1。至于其中的原理,与 python 的数据结构特性有关,感兴趣的可以自行了解,这里就不多费篇幅。
至于为什么要写成 (<value>, )</value>的形式而不是 (<value>)</value>的形式,可以参考下面代码:

type(('string'))
>>
str
type(('string', ))
>>
tuple

除了一次插入一行记录,也可以使用 executemany 一次插入多行数据,代码如下:

persons = [
    ('person 14', 12),
    ('person 15', 20),
    ('person 16', 22),
    ('person 17', 17)
]
cursor.executemany(insert_person_sql, persons)

cursor.execute(quert_sql)
print(cursor.fetchall())
>>
[(1, 'person-1', 20), (2, 'persopn 2', 21), (10, 'person 10', 30), (11, 'person 3', 18), (12, 'person_12', 33), (13, 'person', 18), (14, 'person 14', 12), (15, 'person 15', 20), (16, 'person 16', 22), (17, 'person 17', 17)]

可以看到,我们通过构造了一个含有多行记录的列表,通过 executemany 一次插入数据表中。

使用 sqlite3 库来操作 SQLite 数据库,基本是通过 execute 使用 SQL 语句来完成操作。但是目前网上很多的教程都是简单的演示数据库的增删改查操作,很少针对可能会遇到的问题进行解释。因此本文将一些日常可能会用到的技巧进行了介绍,希望能对使用中遇到问题提供帮助。

Original: https://blog.csdn.net/weixin_37272286/article/details/120312593
Author: SpeculateCat
Title: Python SQLite 数据库插入 Tips

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/816901/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球