zoukankan      html  css  js  c++  java
  • 数据库__DB-API、SQLite

    2019.5.26:(6.4更新~~)

    学习内容:DB-API、了解SQLite(如何选择一个合适的数据库)


    DB-API:

        官方文档:https://www.python.org/dev/peps/pep-0249/  

        重点看:

      

      (thx:https://www.jb51.net/article/104820.htm

      大多数Python数据库接口都遵循Python DB-API标准。

      python给不同数据库提供不同接口。Python中如果要连接数据库,不管是MySQLSQL ServerPostgreSQL亦或是SQLite,使用时都是采用游标的方式,这时DB-API的用处就展现了。

      ‘……’里执行的是SQL语句,具体看那个库怎么定义。

    流程:

     

      1.连接数据库(数据库连接对象--connection)

    """
    connect方法常用参数:
        host: 数据库主机名.默认是用本地主机
        user: 数据库登陆名.默认是当前用户
        passwd: 数据库登陆的秘密.默认为空
        db: 要使用的数据库名.没有默认值
        port: MySQL服务使用的TCP端口.默认是3306
        charset: 数据库编码. utf-8
    """

    """
    connection对象支持的方法:
      cursor()  使用该连接创建并返回游标
      commit()  提交当前事务
      rollback()  回滚当前事务
      close()  关闭连接
    """


    #连接到数据库
    db_conn MySQLdb.connect(host 'localhost'user'root'passwd '123456', db='testdb')
    #获取操作游标
    cursor = db_conn.cursor()
    #关闭游标和连接
    cursor.close()
    db_conn.close()

      2.数据库交互对象--cursor (用于执行查询和获取结果)

      """

       cursor支持的方法:

      execute(op,[,args])    执行一个数据库查询和命令

      fetchone()    取得结果集的下一行

      fetchmany(size)    获取结果集的下几行

      fetchall()    获取结果集中剩下的所有行

      rowcount    最近一次execute返回数据的行数或影响行数

      close()    关闭游标对象

      """

    fetch*()方法: 移动rownumber,返回数据,相当于指针,数组缓冲区的位置

    起始rownumber=0  #设一共6条

    fetchone()    #rownumber=1,取第一条

    fetchmany(3)    #rownumber=4,取第2-4条

    fetchall()    #rownumber=6,取完剩下两条

    用execute执行select选择一个数据库:

    sql="select * form xxx"

    cursor.execute(sql)

    #此时游标指向表xxx的rownumber=0

    用execute执行插入,修改,删除数据库内容

     

      事务:访问和更新数据库的一个程序执行单元  

        原子性:事务中包括的各种操作要么都做要么都不做

        一致性:事务必须使数据库从一致性状态变到另一个一致性状态

        隔离性:一个事务的执行不能背弃她事务干扰

        持久性:事务一旦提交,它对数据库的改变是永久性的

      正确的使用事务:

        关闭自动commit:设置conn.autocommit(False)

        正常结束事务:conn.commit()

        异常结束事务:conn.rollback()  

    try:
    
      sql_insert = "insert into xxx(id , name) values(10,'name10')"
    
      sql_update = "update xxx set name='name91' where id=9 "
    
      sql_delete = "delect form xxx where id<3 "
    
     
    
      cursor.execute(sql.xxxxx)
    
      print cursor.rowcount    #可以得知上一条execute对多少行的数据进行改变
    
      #此时数据库还没有更新,因为没有提交
    
      conn.commit()
    
    except Exception as e:
    
      print e
    
      conn.rollback()    #引入try块,保证事务同时执行或者同时不执行

      

    
    
     




    一个完整的使用(参考语句):
    import sqlite3  #或者MYSQLdb(数据库名字)
    1.连接到数据库
    db_conn = MySQLdb.connect(host = 'localhost', user= 'root', passwd = '123456', db='testdb')
    
    2.获取操作游标
    cursor = db_conn.cursor()
    
    3. 使用 execute 方法执行SQL语句
      cursor.execute("SELECT VERSION()")
    
    
    4.使用 fetchone 方法获取一条数据库。
      dbversion = cursor.fetchone()  
    
    5. 创建数据库
      cursor.execute("create database if not exists dbtest")
    
    
    6.选择要操作的数据库
      db_conn.select_db('dbtest');
    
    
    7.创建数据表SQL语句
      sql = """CREATE TABLE if not exists employee(
             first_name CHAR(20) NOT NULL,
             last_name CHAR(20),
             age INT,  
             sex CHAR(1),
             income FLOAT )"""
    
    8.捕获所有异常:
    try:
        cursor.execute(sql)
    except Exception, e:
        # Exception 是所有异常的基类,这里表示捕获所有的异常
        print "Error to create table:", e
     
    
        9. 插入数据的语句(在10中使用):
    
    sql = """INSERT INTO employee(first_name,last_name, age, sex, income)VALUES ('%s', '%s', %d, '%s', %d)"""
    employees = (
            {"first_name": "Mac", "last_name": "Mohan", "age": 20, "sex": "M", "income": 2000},
            {"first_name": "Wei", "last_name": "Zhu", "age": 24, "sex": "M", "income": 7500},
            {"first_name": "Huoty", "last_name": "Kong", "age": 24, "sex": "M", "income": 8000},
            {"first_name": "Esenich", "last_name": "Lu", "age": 22, "sex": "F", "income": 3500},
            {"first_name": "Xmin", "last_name": "Yun", "age": 31, "sex": "F", "income": 9500},
            {"first_name": "Yxia", "last_name": "Fun", "age": 23, "sex": "M", "income": 3500}
            )
      
    
       10. 元素(employees)写入到表(employee),表再提交到库(dbtest)
    
      try:
    
        # 清空表中数据
        cursor.execute("delete from employee")
        # 执行 sql 插入语句
        for employee in employees:
            cursor.execute(sql % (employee["first_name"], 
                employee["last_name"], 
                employee["age"], 
                employee["sex"], 
                employee["income"]))
       #%叫做通配符,代表任何字符任意数量如'%a%'就代表一个字符串只要包含字母a就符合条件'%a'则代表一个字符串需要以字母a结尾才符合条件‘a%'就是以a开头的字符串了
    
        # 提交到数据库执行
        db_conn.commit()
        # 对于支持事务的数据库, 在Python数据库编程中,
        # 当游标建立之时,就自动开始了一个隐形的数据库事务。
        # 用 commit 方法能够提交事物
    
    except Exception, e:
        # Rollback in case there is any error
        print "Error to insert data:", e
        #b_conn.rollback()
    
    print "Insert rowcount:", cursor.rowcount
    # rowcount 是一个只读属性,并返回执行execute(方法后影响的行数。)
     
    
      11. 数据库查询操作:
    
    #    fetchone()      得到结果集的下一行
    #    fetchmany([size=cursor.arraysize])  得到结果集的下几行
    #    fetchall()      返回结果集中剩下的所有行
    try:
        # 执行 SQL
        cursor.execute("select * from employee")
    
        # 获取一行记录
        rs = cursor.fetchone()
        print rs
    
        # 获取余下记录中的 2 行记录
        rs = cursor.fetchmany(2)
        print rs
    
        # 获取剩下的所有记录
        ars =  cursor.fetchall()
        for rs in ars:
            print rs
        # 可以用 fetchall 获得所有记录,然后再遍历
    except Exception, e:
        print "Error to select:", e
      
    
      12.  数据库更新操作
      sql = "UPDATE employee SET age = age + 1 WHERE sex = '%c'" % ('M')
      #SET是设置语句; where是条件语句;
      try:
        # 执行SQL语句
          cursor.execute(sql)
        # 提交到数据库执行
          db_conn.commit()
          cursor.execute("select * from employee")
          ars =  cursor.fetchall()
          print "After update: ------"
          for rs in ars:
              print rs
      except Exception, e:
        # 发生错误时回滚
          print "Error to update:", e
          db.rollback()
    
    
      13. 关闭数据库连接
       db_conn.close()
     

    SQLite:

      SQLite是一个进程库,实现了一个 :

    自包含的(具有很少的依赖性,相对独立。可以在任何操作系统上运行,甚至可以在简单的嵌入式操作系统中运行。SQLite不使用外部库或接口(除了下面描述的几个标准C库调用之外)), 

    无服务器,(大多数SQL数据库引擎都作为单独的服务器进程实现。想要访问数据库的程序使用某种进程间通信(通常是TCP / IP)与服务器通信,以向服务器发送请求并接收结果。SQLite不能以这种方式工作。使用SQLite,想要访问数据库的进程直接从磁盘上的数据库文件进行读写。没有中间服务器进程。

      无服务器有优点和缺点。主要优点是没有单独的服务器进程来安装,设置,配置,初始化,管理和排除故障。这就是为什么SQLite是一个“ 零配置 ”数据库引擎的原因之一。使用SQLite的程序在运行之前不需要管理支持来设置数据库引擎。任何能够访问磁盘的程序都可以使用SQLite数据库。

      缺点,使用服务器的数据库引擎可以更好地保护客户端应用程序中的错误 - 客户端中的杂散指针不会破坏服务器上的内存。并且因为服务器是单个持久化进程,所以它能够以更高的精度控制数据库访问,从而实现更细粒度的锁定和更好的并发性。

      大多数SQL数据库引擎都基于客户端/服务器。在那些无服务器的情况下,SQLite是本作者唯一知道的,它允许多个应用程序同时访问同一个数据库。) 

    零配置,(SQLite在使用之前不需要“安装”。没有“设置”程序。没有需要启动,停止或配置的服务器进程。管理员无需创建新的数据库实例或为用户分配访问权限。SQLite不使用配置文件。没有什么需要告诉系统SQLite正在运行。系统崩溃或电源故障后无需执行任何操作即可恢复。没有什么可以排除故障。

      其他数据库引擎一旦运行就可以运行得很好。但是,进行初始安装和配置通常会令人生畏。) 

    事务性 (指所有更改和查询都显示为Atomic,Consistent,Isolated和Durable(ACID)的数据库。 即使事务因程序崩溃,操作系统崩溃或计算机电源故障而中断,SQLite 也会实现原子,一致,隔离和持久的可序列化事务。)

      的SQL数据库引擎。使用的是c语言。SQLite是一个嵌入式SQL数据库引擎。与大多数其他SQL数据库不同,SQLite没有单独的服务器进程。SQLite直接读写普通磁盘文件。具有多个表,索引,触发器和视图的完整SQL数据库包含在单个磁盘文件中。

      客户端/服务器SQL数据库引擎努力实现企业数据的共享存储库。它们强调可伸缩性,并发性,集中化和控制。SQLite致力于为各个应用程序和设备提供本地数据存储。SQLite强调经济,效率,可靠性,独立性和简单性。

      注意:a。避免在直接访问相同数据库(没有中间应用程序服务器)和同时通过网络从多台计算机访问的情况下使用SQLite。

        b。SQLite通常可以正常工作作为网站的数据库后端。但是,如果网站是写密集型或者繁忙而需要多个服务器,那么请考虑使用企业级客户端/服务器数据库引擎而不是SQLite。

        c。SQLite数据库的大小限制为140 TB(2 47字节,128 tibibytes)。即使它可以处理更大的数据库,SQLite也会将整个数据库存储在一个磁盘文件中,并且许多文件系统将文件的最大大小限制为小于此值。因此,如果您正在考虑如此规模的数据库,您最好考虑使用客户端/服务器数据库引擎,将其内容分布在多个磁盘文件中,也可能跨多个卷。

        d。不建议使用在高并发性:SQLite支持无限数量的同时读者,但在任何时刻它只允许一个编写者。

    因此:

      如何选择一个正确的数据可引擎:

    • 数据是否通过网络与应用程序分离?→选择客户端/服务器
    • 许多并发writers?→选择客户端/服务器
    • 大数据?→选择客户端/服务器
    • 否则→选择SQLite!

      对于具有低写入器并发性和小于1TB内容的设备本地存储,SQLite几乎总是更好的解决方案。SQLite快速可靠,无需配置或维护。它保持简单。SQLite“正常”。手机,游戏机等广泛使用。

    SQLite的c/c++ api应用:https://sqlite.org/cintro.html

  • 相关阅读:
    Python全栈-第六课 学习笔记
    python基础 day27 装饰器函数classmethod、staticmethod
    python基础 day26 面向对象-super方法、封装、property装饰器、反射
    python基础 day25 面向对象-继承2
    python基础 day24 面向对象-继承1
    python基础 day23 面向对象2
    python基础 day22 面向对象
    python基础 day21 递归函数、shutil模块
    python基础 day20 re模块、带参数的装饰器
    python基础 day19 正则表达式
  • 原文地址:https://www.cnblogs.com/marvintang1001/p/10930837.html
Copyright © 2011-2022 走看看