1.sqlite3最小数据库介绍
SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。
——来自菜鸟教程
说白了就是不用安装其他数据库软件,以文件的方式存储数据2.连接数据库
数据库其实就是一个文件,每次相当于通过读取这个文件来连接数据。在调用connect函数的时候,指定库名称,如果指定的数据库存在就直接打开这个数据库,如果不存在就新创建一个再打开。
import sqlite3
conn = sqlite3.connect('data.db')
4.创建游标
我们需要使用游标对象SQL语句增删改查。 通过以下方法来定义一个游标。
cursor = conn.cursor()
4.执行sql语句
cursor.execute('create table if not exists user(name varchar(20),age varchar(20))')
cursor.execute("select * from user")
cursor.execute("insert into user (name, age) values(?,?)", ('1', '2'))
cursor.execute("insert into user (name, age) values('%s','%s')" % ("张三", "16"))
5.提交更改
执行这句会提交修改到数据库,否则只在本地缓存有效,下次启动会数据丢失,可以在程序结束前判断是否修改过数据,然后执行提交。
conn.commit()
6.关闭数据库
cursor.close()
conn.close()
7.游标cursor的附录操作:
函数 | 说明 |
---|---|
execute() | 执行sql语句 |
executemany() | 执行多条sql语句 |
fetchone() | 从结果中取一条记录,并将游标指向下一条记录 |
fetchmany() | 从结果中取多条记录 |
fetchall() | 从结果中取出所有记录 |
8.常用的sqlite语句
1.判断数据库是否为空
cursor.execute("select count(*) from sqlite_master")
if cursor.fetchall()[0][0] == 0:
print("警告,数据库丢失")
2.设置id自增
# 创建表
"create table person (id INTEGER PRIMARY KEY,name varchar(10))"
# 插入
"insert into person(id,name) values(null,?)",('张三')
3.插入一条记录后返回自增的主键
"select last_insert_rowid() from video"
9.连接的工具类
这个不好,垃圾,用最下边那个。
import sqlite3
conn = None
cursor = None
def get_conn_cursor():
if conn is None:
connect_to_sqlite()
return conn, cursor
def connect_to_sqlite():
global conn
global cursor
conn = sqlite3.connect('data.db', check_same_thread=False)
cursor = conn.cursor()
def close_sqlite():
global conn
global cursor
cursor.close()
conn.close()
# from app.src.mapper.connector import get_conn_cursor,close_sqlite
# conn, cursor = get_conn_cursor()
# close_sqlite()
10.常见错误
1.sqlite默认是单线程的,是因为根本没必要多线程,限制他效率的不是线程。
2.有时会出现sqlalchemy.exc.ProgrammingError:(sqlite3.ProgrammingError)错误,因为他默认在线程中创建的SQLite对象只能在同一个线程中使用,所以多线程调用时会出现错误,这样创建就会忽略线程间的调用。
conn = sqlite3.connect('data.db', check_same_thread=False)
3.遇到Recursive use of cursors not allowed错误。这是因为你既然忽略了多线程间调用的警告,sqlite是单线程的,多线程下肯定会出问题,比如cursor查到一半,另一个线程又调用了cursor,就会出现问题,所以要用锁限制一下,下面是一个简单的连接类,可以对他继续拓展(顺便说一下,尽量避免多次调用commit)
import sqlite3
import threading
from app.main.config import Config
lock = threading.Lock()
conn = sqlite3.connect(Config.DB_FILE_NAME, check_same_thread=False)
cursor = conn.cursor()
def execute(sql, args=()):
try:
lock.acquire(True)
cursor.execute(sql, args)
finally:
lock.release()
def select(sql, args=()):
try:
lock.acquire(True)
cursor.execute(sql, args)
return cursor.fetchall()
finally:
lock.release()
def commit():
try:
lock.acquire(True)
conn.commit()
finally:
lock.release()