• [python] 基于Dataset库操作数据库


    dataset库是Python中一个用于操作数据库的简单库,它提供了一种简洁的方式与各种关系型数据库进行交互,例如SQLite、MySQL、PostgreSQL 等。你可以使用dataset库来执行查询、插入、更新和删除操作,而无需编写复杂的SQL语句。dataset库适用于小规模的数据存储和查询场景,相比csv和json文件只能通过编程语言来处理数据,dataset支持使用SQL语言进行查询,提供了丰富的查询功能和灵活性。对于大规模数据和高并发场景,专业数据库系统如MySQL、PostgreSQL等更具优势。

    dataset官方仓库地址:dataset。dataset官方文档地址:dataset-doc。安装命令如下:

    pip install dataset

    import dataset
    # 查看版本
    dataset.__version__
    '1.6.2'

    1 使用说明

    1.1 数据库操作

    数据库创建

    connect函数是dataset库中用于连接到数据库并返回一个数据库对象。它的使用方式如下:

    # 创建一个连接到名为mydatabase.db的SQLite数据库的对象
    # 如果要连接的数据库不存在,则自动创建
    db = dataset.connect('sqlite:///mydatabase.db')
    # 如果要连接到MySQL数据库(需要安装相应组件),可以使用以下语法:
    # db = dataset.connect('mysql://user:password@localhost/mydatabase')
    # 如果要连接到PostgreSQL数据库(需要安装相应组件),可以使用以下语法:
    # db = dataset.connect('postgresql://user:password@localhost/mydatabase')

    表格查询与创建

    dataset提供get_table函数或直接表名索引来创建或加载一个表格。同时,dataset也提供create_table函数创建一个新的表格,也可以使用load_table函数加载现有的表格。

    # 使用db['table_name']语法获取指定表的引用,其中table_name是表的名称
    # 如果表不存在,dataset库将自动创建它,但是只有数据插入才会保存
    table = db['mytable']
    # 或者使用如下函数:
    # table = db.get_table('mytable')
    # 创建一个新表格,原有表格会被覆盖
    # 该表没有自定义的主键或类型。Dataset库会默认创建一个名为 'id' 的整数类型的主键。
    table = db.create_table('mytable')

    此外也可以指定表格创建时的各种参数,dataset主要支持类型有:

    • db.types.integer:表示整数类型。
    • db.types.float:表示浮点数类型。
    • db.types.boolean:表示布尔类型。
    • db.types.datetime:表示日期时间类型。
    • db.types.date:表示日期类型。
    • db.types.text:表示文本字符串类型。
    # 指定了自定义主键为 'age'
    # db.create_table('mytable', 'age')
    # 指定了自定义的主键为 'city',并且指定该主键的类型为文本类型
    # db.create_table('mytable', primary_id='city', primary_type=db.types.text)
    # 指定没有主键
    # db.create_table('mytable', primary_id=False)
    # 加载现有表格
    table = db.load_table('mytable')
    # 如果表格不存在,则会报错
    # table = db.load_table('user')
    # 也可以通过has_table函数查询是否存在某个表
    db.has_table('user')
    False
    # 查看当前数据库下所有表格
    db.tables
    []

    直接在数据库上运行sql查询语句

    dataset库提供query函数用于过滤和查询数据集。它接受一个字符串参数,该参数表示一条 SQL 查询语句,用于选择符合条件的数据。

    # statement = 'SELECT * FROM mytable'
    # for row in db.query(statement):
    # print(row)

    1.2 表格操作

    插入数据

    # 使用db['table_name']语法获取指定表的引用,其中table_name是表的名称
    # 如果表不存在,dataset库将自动创建它
    table = db['mytable']

    insert用于插入数据。

    # 插入一条包含名字、年龄和电子邮件的记录
    data = {'name': 'John', 'age': 25, 'email': 'john@example.com'}
    table.insert(data)
    # 插入一条包含名字、年龄,电子邮件的记录为空
    table.insert(dict(name='Alice', age=25))
    2

    insert_ignore用于插入一行数据,但只有在keys中列的值不重复时才会插入。

    table.insert_ignore(dict(name='Alice', age=25),keys=['name'])
    False

    insert_many函数用于向数据库表中批量插入数据。它接受一个列表作为参数,该列表中的每个元素都是一个字典,表示要插入的一行数据。使用该函数要比逐个添加快很多。

    data = [
    {'name': 'John', 'age': 25, 'city': 'New York'},
    {'name': 'Alice', 'age': 30, 'city': 'Los Angeles'},
    {'name': 'Bob', 'age': 35, 'city': 'San Francisco'}
    ]
    table.insert_many(data)

    插入列

    # 插入名为 key 的列,数据类型为文本(text),并且设置了唯一约束(unique=True)
    # table.create_column('key', db.types.text,unique=True)
    # 插入名为 food 的列,数据类型为文本(text)
    table.create_column('food', db.types.text)
    # 创建一个列,第一个值为列名,第二个值用于自动猜测该列的类型
    table.create_column_by_example('length', 4.2)

    查看数据

    # 查看表格行数
    len(table)
    5
    # 获取表中的所有数据
    data = list(table.all())
    # 打印数据
    for row in data:
    print(row)
    OrderedDict([('id', 1), ('name', 'John'), ('age', 25), ('email', 'john@example.com'), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 2), ('name', 'Alice'), ('age', 25), ('email', None), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 3), ('name', 'John'), ('age', 25), ('email', None), ('city', 'New York'), ('food', None), ('length', None)])
    OrderedDict([('id', 4), ('name', 'Alice'), ('age', 30), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 35), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
    # 直接打印数据
    for row in table:
    print(row)
    OrderedDict([('id', 1), ('name', 'John'), ('age', 25), ('email', 'john@example.com'), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 2), ('name', 'Alice'), ('age', 25), ('email', None), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 3), ('name', 'John'), ('age', 25), ('email', None), ('city', 'New York'), ('food', None), ('length', None)])
    OrderedDict([('id', 4), ('name', 'Alice'), ('age', 30), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 35), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
    # 表的列名
    table.columns
    ['id', 'name', 'age', 'email', 'city', 'food', 'length']
    # 是否存在某列
    table.has_column('sex')
    False

    查找数据

    # 根据字段查找
    results = table.find(name='John')
    # 遍历结果
    for row in results:
    print(row['name'], row['city'])
    John None
    John New York
    # 多字段查找
    results = table.find(name='John',city=None)
    # 遍历结果
    for row in results:
    print(row['name'], row['city'])
    John None
    # 仅返回第一个结果
    results = table.find_one(name='John')
    results
    OrderedDict([('id', 1),
    ('name', 'John'),
    ('age', 25),
    ('email', 'john@example.com'),
    ('city', None),
    ('food', None),
    ('length', None)])
    # 基于id查询
    results = table.find(id=[1, 2, 4])
    # 遍历结果
    for row in results:
    print(row['name'], row['city'])
    John None
    Alice None
    Alice Los Angeles
    # 找出age大于等于30的结果
    results = table.find(age={'>=': 30})
    for row in results:
    print(row['name'], row['age'])
    Alice 30
    Bob 35
    # 找出age在21到30之间的结果
    results = table.find(age={'between': [21, 30]})
    for row in results:
    print(row['name'], row['age'])
    John 25
    Alice 25
    John 25
    Alice 30
    # 筛选某个字段下的唯一项
    results = table.distinct('name')
    for row in results:
    print(row)
    OrderedDict([('name', 'Alice')])
    OrderedDict([('name', 'Bob')])
    OrderedDict([('name', 'John')])

    dataset库还支持更丰富的查询操作,具体可以查看文档:dataset-query

    更新数据

    update函数用于更新单条记录。

    # 第一参数为要更新的字段和对应的新值,如果字段不存在则会添加该字段
    # 第二个参数keys用于指定根据哪些列来筛选要更新的对象
    # 下面代码表示将name为'John'的行更新数据
    affected_rows = table.update(dict(name= 'John',age=23,email="qq.com"), keys=['name'])
    print("受影响的行数:", affected_rows)
    受影响的行数: 2
    # 获取表中的所有数据
    data = list(table.all())
    # 打印数据
    for row in data:
    print(row)
    OrderedDict([('id', 1), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 2), ('name', 'Alice'), ('age', 25), ('email', None), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 3), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', 'New York'), ('food', None), ('length', None)])
    OrderedDict([('id', 4), ('name', 'Alice'), ('age', 30), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 35), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])

    update_many也被提供用于批量更新数据。

    # 更新多行数据
    rows = [
    {'name': 'Alice', 'age': 123},
    {'name': 'Bob', 'age': 18}
    ]
    # 该函数没有返回值
    table.update_many(rows,keys=['name'])

    此外也可以用upsert和upsert_many插入更新单条或多条记录,即如果存在具有匹配关键字的行,则这些行将被更新,否则将在表中插入新行。具体使用类似update和update_many。

    删除数据

    delete函数用于删除行,如下所示:

    for row in table:
    print(row)
    OrderedDict([('id', 1), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 2), ('name', 'Alice'), ('age', 123), ('email', None), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 3), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', 'New York'), ('food', None), ('length', None)])
    OrderedDict([('id', 4), ('name', 'Alice'), ('age', 123), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
    # 删除age为23的记录
    table.delete(age=23)
    for row in table:
    print(row)
    OrderedDict([('id', 2), ('name', 'Alice'), ('age', 123), ('email', None), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 4), ('name', 'Alice'), ('age', 123), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
    # 删除age为30且name为'John'的记录
    table.delete(age=30, name='John')
    for row in table:
    print(row)
    OrderedDict([('id', 2), ('name', 'Alice'), ('age', 123), ('email', None), ('city', None), ('food', None), ('length', None)])
    OrderedDict([('id', 4), ('name', 'Alice'), ('age', 123), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
    # 找出age大于等于30的结果
    table.delete(age={'>=': 30})
    for row in table:
    print(row)
    OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])

    drop_column函数会从数据集中删除指定的列,如下所示:

    # sqlite不支持
    # table.drop_column('age')
    # for row in table:
    # print(row)

    1.3 事务操作

    事务是一组数据库操作,要么全部成功执行,要么全部回滚。这可以确保数据的一致性和完整性。下面代码展示了如何创建一个事务对象。在这种情况下,所有更新都会立即提交,或者,在出现异常的情况下,立即回滚所有操作。事务通过上下文管理器得到支持,因此可以通过with语句使用:

    with dataset.connect('sqlite:///mydatabase.db') as tx:
    # 在这里执行数据库操作
    # 如果所有操作都成功,事务会自动提交
    # 如果发生错误,事务会自动回滚
    tx['user'].insert(dict(name='John Doe', age=46, country='China'))

    当然以上代码可以显式调用函数begin、commit和rollback来获得相同的功能:

    db = dataset.connect('sqlite:///mydatabase.db')
    db.begin()
    try:
    db['user'].insert(dict(name='John Doe', age=46, country='China'))
    db.commit()
    except:
    db.rollback()

    除此之外,也支持嵌套事务如下所示:

    db = dataset.connect()
    with db as tx1:
    tx1['user'].insert(dict(name='John Doe', age=46, country='China'))
    with db as tx2:
    tx2['user'].insert(dict(name='Jane Doe', age=37, country='France', gender='female'))

    2 参考

  • 相关阅读:
    深信服2023秋季校园招聘C++笔试A卷
    Vscode远程调试及gdbserver配置
    黑马瑞吉外卖之菜品的启售停售
    1032 Sharing(链表)
    NLP---文本前期预处理的几个步骤
    2023-11-16 android 编译提示module freg.default missing dependencies:
    数据导入与预处理-拓展-pandas时间数据处理02
    2023电工杯数学建模A题思路模型代码
    Linux15 --- 信号量
    解决在远程连接的linux服务器上调用matplotlib画图的问题
  • 原文地址:https://www.cnblogs.com/luohenyueji/p/17934693.html