Python基础 - Sqlite3基本使用

孔砚
2023-12-01

​ SQLite是C库,提供一个基于磁盘的轻量级的数据库,允许使用非标准的SQL查询语言访问数据库,不需要一个单独的服务进程。一些程序可以使用SQLite作为内部数据存储。

  1. 使用sqlite3模块,首先创建一个数据库连接对象;
# 创建sqlite目录,指定新的工作目录
import os
os.system('mkdir sqlite')
os.chdir('C:\\PythonDemo\\sqlite')
import sqlite3
# 可以使用:memory:在内存中创建数据库
conn = sqlite3.connect('demo.db')
  1. 拥有Connection对象后,可以创建一个Cursor对象然后调用execute方法来执行SQL命令;
# 创建游标对象
c = conn.cursor()
# 创建stocks表
c.execute('''CREATE TABLE stocks(date text, trans text, symbol text, qty real,price real)''')
# 插入一条数据
c.execute("INSERT INTO stocks VALUES ('2022-08-18','BUY','RHAT',110,45.5)")
# 提交修改
conn.commit()
# 关闭数据库连接
conn.close()
  1. 在字符串中直接拼接SQL是不安全的,可以使用占位符解决;
# 不安全的做法
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol='%s'" % symbol)
# 正确的做法
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print(c.fetchone())
# 一次添加多条记录
purchases = [('2022-08-28', 'BUY', 'IBM', 1000, 45.00),
             ('2022-08-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2022-08-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)
  1. 执行完select语句后,可以使用cursor作为迭代器提取数据,调用cursor的fetchone方法可以提取出一条匹配行,调用fetchall获取匹配到的列表,再次调用则取不到数据了。
>>> for row in c.execute('SELECT * FROM stocks ORDER BY price'):
	print(row)

('2022-08-28', 'BUY', 'IBM', 1000.0, 45.0)
('2022-08-18', 'BUY', 'RHAT', 110.0, 45.5)
('2022-08-06', 'SELL', 'IBM', 500.0, 53.0)
('2022-08-05', 'BUY', 'MSFT', 1000.0, 72.0)

Connection对象

class sqlite3.Connection

isolation_level隔离级别,取值为DEFERRED、IMMEDIATE、EXCLUSIVE、None,自动提交是None。

in_transaction只读属性,True表示开启了事务。

cursor(factory=Cursor)方法接受一个可选的factory参数。如果提供,它必须是一个可调用对象,返回Cursor或其子类的实例。

commit()方法提交当前的事务。如果没有调用commit()方法,数据库的操作对于其他数据库连接不可见。

rollback()方法撤销从上次提交后的任意数据库变更。

close()方法用于关闭数据库连接,close()方法不会自动调用commit()方法提交。

execute(sql[,parameters])方法是一个非标准的快捷方式,它通过调用cursor()方法来创建一个游标对象,然后使用给定的参数调用游标的execute()方法,然后返回游标对象。

executemany(sql[,parameters])方法是一个非标准的快捷方式,它通过调用cursor()方法来创建一个游标对象,然后用给定的参数调用游标的executemany()方法,然后返回游标对象。

create_function(name, num_params,func)创建一个用户定义的函数,以后可以在函数名的名称下从SQL语句中使用该函数。num_params是函数接受的参数数量(如果num_params为-1,函数可以接受任意数量的参数),而func是一个Python可调用对象,作为SQL函数调用。该函数可以返回SQLite支持的任何类型:bytes, str, int, float和None。

import sqlite3
improt hashlib

def md5sum(t):
    return hashlib.md5(t).hexdigest()

con = sqlite3.connect(':memory:')
con.create_function("md5", 1, md5sum)
cur = con.cursor()
cur.execute('select md5(?)', (b"foo",))
print(cur.fetchone()[0])

create_aggregate(name, num_params, aggregate_class)创建用户定义的聚合函数。

import sqlite3

class MySum:
    def __init__(self):
        self.count = 0
	# 聚合类必须包含一个step方法,可以接受num_params个参数,-1则可以接受任意数量的参数
    def step(self, value):
        self.count += value
	# finalize方法返回聚合函数最终的结果
    def finalize(self):
        return self.count

con = sqlite3.connect(":memory:")
con.create_aggregate("mysum", 1, MySum)
cur = con.cursor()
cur.execute("create table test(i)")
cur.execute("insert into test(i) values (1)")
cur.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
print(cur.fetchone()[0])

create_collation(name, callable)使用指定的名称和callable创建排序规则。

import sqlite3

def collate_reverse(string1, string2):
    if string1 == string2:
        return 0
    elif string1 < string2:
        return 1
    else:
        return -1

con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)
cur = con.cursor()
cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
    print(row)
con.close()
# 删除排序规则
con.create_collation("reverse", None)

interrupt()方法可以从不同的线程调用此方法,以中止可能在连接上执行的任何查询。然后查询将中止,调用者将得到一个异常。

row_factory可以将此属性更改为一个可调用对象,该可调用对象接受游标和原始行作为元组,并返回实际结果行。通过这种方式,您可以实现更高级的返回结果的方法。

import sqlite3

def dict_factory(cursor, row): 
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print(cur.fetchone()["a"])

iterdump()以SQL文本格式转储数据库,返回迭代器,把一个内存数据库中的数据转储时很有用。

import sqlite3
con = sqlite3.connect("demo.db")
with open('dump.sql', 'w') as f:
    for line in con.iterdump():
        f.write("%s\n"%line)

Cursor对象

class sqlite3.Cursor

execute(sql[, parameters]) 执行SQL语句,SQL语句可以是参数化的,支持问号占位符以及命名占位符的方式。

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table people (name_last, age)")
who = "Thoms"
age = 24
# 问号占位符方式,execute方法只能执行一条SQL,executescript方法可以执行多条SQL
cur.execute("insert into people values (?, ?)", (who, age))
# 命名占位符方式
cur.execute("select * from people where name_last=:who and age=:age", {"who":who, "age": age})
print(cur.fetchone())

executemany(sql, seq_of_parameters) 对序列seq_of_parameters中的所有参数序列或映射执行SQL命令。

import sqlite3

class IterChars:
    def __init__(self):
        self.count = ord('a')

    def __iter__(self):
        return self

    def __next__(self):
        if self.count > ord('z'):
            raise StopIteration
        self.count += 1
        return (chr(self.count - 1),) # this is a 1-tuple

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")
theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)
cur.execute("select c from characters")
print(cur.fetchall())

生成器的简单例子

import sqlite3
import string

def char_generator():
    for c in string.ascii_lowercase:
        yield (c,)

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")
cur.executemany("insert into characters(c) values (?)", char_generator())
cur.execute("select c from characters")
print(cur.fetchall())

executescript(sql_script)这是一次执行多个SQL语句的一种非标准的方便方法。它首先发出一个COMMIT语句,然后执行作为参数获取的SQL脚本。

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.executescript("""
    create table person(
        firstname,
        lastname,
        age
    );

    create table book(
        title,
        author,
        published
    );

    insert into book(title, author, published)
    values (
        'Dirk Gently''s Holistic Detective Agency',
        'Douglas Adams',
        1987
    );
    """)

fetchone():获取查询结果集的下一行,返回单个序列,或在没有更多数据可用时返回None。

fetchmany(size=cursor.arraysize)获取查询结果的下一组行,返回一个列表。当没有更多的行可用时,返回一个空列表。每次调用获取的行数由size参数指定。如果没有指定,游标的arraysize将决定要获取的行数。该方法应该尝试获取size参数所指示的尽可能多的行。如果由于指定的行数不可用而不可能这样做,则可能返回更少的行。注意size参数涉及到性能方面的考虑。为了获得最佳性能,通常最好使用arraysize属性。

fetchall()获取查询结果的所有行,返回一个列表。注意,游标的arraysize属性会影响此操作的性能。如果没有可用的行,则返回空列表。

close()立即关闭游标,调用后游标将不可用。

Row对象

class sqlite3.Row

Row实例用作Connection对象的高度优化的row_factory。它支持通过列名和索引、迭代、表示、相等测试和len()进行映射访问。如果两个Row对象具有完全相同的列并且它们的成员相等,则它们比较时相等。

conn = sqlite3.connect(":memory:")
c = conn.cursor()
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')
c.execute("""insert into stocks
          values ('2022-08-18','BUY','RHAT',100,35.24)""")
conn.commit()
c.close()

conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from stocks')
r = c.fetchone()
type(r)
tuple(r)
len(r)
r[2]
r.keys()  # 返回表的列名列表
r['qty']
for member in r:
    print(member)

SQLite和Python类型

Python类型SQLite类型
NoneNULL
intINTEGER
floatREAL
strTEXT
bytesBLOB
 类似资料: