天天看点

(14)Py数据库DBI

1、MySQLdb模块

MySQLdb是针对mysql连接做了python的封装,并提供接口,

我们可以在python中连接MySQLdb来实现数据的各种操作。官方Introduction :

MySQLdb is an thread-compatible interface to the popular MySQL \

database server that provides the Python database API.。

它其实相当于翻译了对应C的接口。需要注意的地方是:Python3.6系列中的MySQL库更名为mysqlclient。

DB-API规范的属性:

  apilevel DB-API 模块兼容的 DB-API 版本号

  threadsafety 线程安全级别,0表示不支持线程安全,3表示支持完整的线程安全

  paramstyle 该模块支持的 SQL 语句参数风格

DB-API阐明一系列所需对象和数据库访问机制的标准,它可以为不同数据库的数据库适配器和底层数据库

提供统一的一致性访问,使不同数据库间移植代码变得容易,它时强需求驱动的。

首先:解释一下MYSQL的C语言API接口:

1)创建并初始化MYSQL句柄 ;

          MYSQL  var1 = mysql_init();    或者

          MYSQL  var2 ;   mysql_init(&var2);

2) 调用mysql_real_connect,绑定句柄与数据连接

  MYSQL *STDCALL mysql_real_connect(MYSQL *mysql, const char *host, \

   const char *user, const char *passwd,  const char *db,  \

   unsigned int port,  const char *unix_socket,  unsigned long clientflag);

  成功返回1 , 失败返回0

3) 调用mysql_real_query函数进行数据库查询

  int STDCALL mysql_real_query(MYSQL *mysql, const char *q, unsigned long length);

4) 取查询结果

  MYSQL_RES *  STDCALL mysql_store_result(MYSQL *mysql);

  MYSQL_RES *  STDCALL mysql_use_result(MYSQL *mysql);

  第一种:将从Mysql服务器查询的所有数据都存储到客户端

  第二种:初始化检索,以便于后面一行一行的读取结果集,而它本身并没有从服务器读取任何数据

   这种方式较之第一种速度更快且所需内存更少,但它会绑定服务器,阻止其他线程更新任何表,

而且必须重复执行mysql_fetch_row读取数据,直至返回NULL,否则未读取的行会在下一次查询时作

为结果的一部分返回,故经常我们使用mysql_store_result。

5) 取结果集

   MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);

   返回MYSQL_ROW型的变量,即字符串数组

6)释放结果集,防止内存泄露

   void  STDCALL mysql_free_result(MYSQL_RES *result);

7)关闭数据库连接

   oid STDCALL mysql_close(MYSQL *sock);

然后:MYSQL的python语言API接口:

Python DB-API为开发人员提供了数据库应用编程接口,包括两个对象

DBM是一种古老的UNIX持久化存储机制,它基于文件。

数据库访问包括:直接访问数据库接口,和使用ORM访问两种方式

1、导入Mysqldb模块

    # -*- coding: UTF-8 -*-

    import MySQLdb

2、Connection对象

a)生成连接对象(句柄)

conn = MySQLdb.connect(host="localhost",user="root",passwd="jb51",db="test",charset="utf8")

常用的参数包括:

host:数据库主机名.默认是用本地主机 port:MySQL服务使用的TCP端口.默认是3306    

user:数据库登陆名.默认是当前用户        passwd:数据库登陆的秘密.默认为空

db:要使用的数据库名.没有默认值          charset:数据库编码

unix_socket:字符串类型,指定unix套接字的位置                       

b)建立“连接”的对象,提供以下方法

a.  conn.close():关闭此connect对象, 关闭后无法再进行操作,除非再次创建连接

b.  conn.commit(): 提交当前事务,支持事务的数据库执行增删改后; 没有commit则数据库默认回滚,即提交执行

c.  conn.rollback():   取消当前事务

d.  conn.set_character_set("charset")   设置字符集

e.  conn. set_sql_mode("sqlmod")    设置SQL模式风格

常有属性:

 conn.host  ==> 已经链接的主机    

 conn.user ==> 链接使用的用户   conn.passwd  ==> 链接使用的密码

 conn.db  ==> 链接使用的数据库  conn.port  ==> 链接使用的端口

 conn.unix_socket  ==> 链接使用

 conn.init_command   conn.sql_mode    conn.ssl     conn.local_infile  

3、Cursor对象

a)创建游标对象(指针)

      curfd = conn.cursor():

  Python DB-API总能提供游标对象,即使在不支持游标的数据库系统中,

  也能有效模仿。它可以让用户提交数据库指令,并获得查询结果

b)使用“游标”对象, 提供以下方法

 a. curfd.execute(sql[, args])           执行SQL语句,返回取到的条数(long int)

 b. curfd.close():                       关闭此游标对象

 c. curfd.fetchone():                    得到结果集的下一行,返回元组

 d. curfd.fetchmany([size = cursor.arraysize]):   得到结果集的下几行

 e. curfd.fetchall():                    得到结果集中剩下的所有行

 f. curfd.excutemany(sql, args):         执行多个数据库查询或命令

 g. curfd.callproc(func [, args])        调用存储过程

   curfd.connection:创建此游标对象的数据库连接

   curfd.arraysize:使用fetchmany()方法一次取出多少条记录,默认为1

   curfd.lastrowid:相当于PHP的last_inset_id(),上次修改行的行id

   curfd.rowcount:上次执行execute处理影响的行数

   curfd.messages:游标执行后获取的消息信息

   curfd.rownumber:当前结果集合中游标的索引

事务型数据库:是指作为单个逻辑工作单元执行的一系列操作,

要么完整地执行,要么完全地不执行。

总结:

使用Python的DB-API时,只要搞清楚Connection对象和Cursor对象,打开后一定记得关闭,就可以放心地使用。

使用Cursor对象执行insert,update,delete语句时,执行结果由rowcount返回影响的行数,就可以拿到执行结果。

使用Cursor对象执行select语句时,通过featchall()可以拿到结果集。

结果集是一个list,每个元素都是一个tuple,对应一行记录。

如果SQL语句带有参数,那么需要把参数按照位置传递给execute()方法,

有几个?占位符就必须对应几个参数,例如:

cursor.execute('select * from user where name=? and pwd=?', ('abc', 'password'))

SQLite支持常见的标准SQL语句以及几种常见的数据类型。具体文档请参阅SQLite官方网站。

2、DBMS数据库管理系统

=============================================================================

有关:数据库原理、并发行、模式、原子性、完整性、恢复、复杂左连接、触发器、

查询优化、事务性、存储过程等知识,需要专门是书籍做教程。

数据库管理系统DBMS ============== MySQL、Oracle、SQLServer、MySQL、SQLite等

概念理解:

   数据库

   数据表

   数据行

MYSQL的常见操作:

   创建数据库 ==> create database name;

   选择数据库 ==> use databasename;

   直接删除数据库,不提醒 ==> drop database name

   显示所有表 ==> show tables;

   显示表结构 ==> describe tablename;

   创建数据表 ==> create table tab_name(id int , name varchar(20));

   删除数据表 ==> delete table tab_name ;

   修改表结构 ==>

   alter table oldtable rename newtable; #修改表名

   alter table tablename add age float after name; #新增字段,并指定位置

   alter table tablename drop column age ; #删除字段,通过名字

   alter table tablename modify name varchar(20); #改表结构中字段名

   alter table tablename change name newname varchar(20); #改表结构中字段属性

   增加表记录 ==> insert into tab_name(id, name) volumes(1, 'alex');

   删除表记录 ==> delete from tab_name where id = xx;

   修改表记录 ==> update tab_name set name = xxx where id = yyy ;

   查询表记录 ==> select * from  tab_name limit 5;

   用户操作指令:

create user 'username'@'ip_address' identified by 'passwd';  # 创建新用户

drop user 'username'@'ip_address'  # 删除原用户

rename user 'userold'@'ip_address' to 'usernew'@'ip_address'  #修改用户名

       set password for 'username'@'ip_address' = PASSWORD('passwd')  #修改用户密码

一些常见的概念:

引擎:

  MyISM 引擎 == 不支持事务

  InnoDB引擎 == 全文搜索引擎,查询更快;支持事务,原子性操作

事务:

  原子性操作 == 多个操作被封装成一个事务;事务成功意味着所有操作成功,事务失败意味所有操作均失败

字段属性:

  是否为空 not null

  默认值  default  val

  自增列  auto_increment (一张表只能有一个自增列,必须是数字,而且是索引 —— 这里的索引是主键)  

索引:

  唯一索引  一张表可以有多个唯一列,不能重复但可以为空null

  主键索引  primary key (一张表只能有一个主键,主键是唯一且不能重复,不能为空,主键可以是多列)

外键性:

  一张表的字段受另一张表字段的约束,就是外键;外键可以有多个(constraint 约束)

修改字段属性:

  添加主键:alter table tab_name add primary key(column)

  删除主键:alter table tab_name drop primary key ;

            alter table tab_name modify column 类型,drop primary key .

添加外键:alter table tab_slave add constraint 外键名称 foreign key tab_slave(var1) references tab_master(var2)

删除外键:alter table tab_slave drop foreign key 外键名称

修改默认值:alter table tab_name alter column set default valume;

删除默认值:alter table tab_name alter colume delete default;

MYSQL的字段类型:

   bit(m) : 二进制位

数字:

   tinyint : 小整数 (0-255)unsigned(-128~127) signed

smallint: 小整数  

int : 整数 unsigned signed

bigint : 大整数 unsigned signed

decimal(m,d) : 十进制位 —— 精确的,总位位数m,小数点后位数d

FLOAT : 浮点型

DOUBLE : 双精度

字符串:

char(m): 字符串类型 —— 定长,固定长度,必须分配的内存空间

varchar(m): 字符串类型 —— 变长,最大长度,内存分配根据实际需要而定

text: 大字符串

mediumtext: 大字符串

longtext : 大字符串

二进制:

TinyBlob : 二进制数据存储

Blob : 强制二进制数据

MediumBlob :

LongBlob :

时间:

DATE : YYYY-MM-DD 具体时间

TIME : HH:MM:SS

YEAR : YYYY

DATETIME : YYYY-MM-DD HH:MM:SS

TIMESTAMP : YYYYMMDD HHMMSS

特殊数据类型:

枚举:enum ,这有点类似字典,调用方式:name.x

enum  name:    create table tab_name(

x = one ;        name varchar(20),

y = tow ;        size  enum("x" , "y" , "z"));

z = thress ;     insert into tab_name(name,size) volumes("liujian","x")("liuyong","y");

集合:set

set  name:              

x = one, tow, thress ;                  

create table tab_name(name varchar(20),size set("x" , "y" , "z"));

insert into tab_name(name,size) volumes("liujian","x,y");

MYSQL的表关系:

表复制:

  insert into tab_master(columu1,columu2) select columu3,columu4 from tab_slave;

条件:

  select * from tab_name where id > 2 and name != 'alex' and phone in (152,123);

通配符:

  slect * from tab_name where name link 'ale%' ; # ==> % 任意多个字符 _任意一个字符

分页:

select * from tab_name limit a,b ; ; # ==> 从第a行开始,取出b行数据

select * from tab_name limit b offset a ;  # ==> 从第a行开始,取出b行数据

排序:

select * from tab_name order by columu asc/desc; #[asc == 从小到大, desc == 从大到小]

columu [asc/desc] 可以排序多次,第二次开始排序处理上次排序相同的记录

分组:

select * from tab_name group by columu; # ==> 分组会根据columu去掉相同项

select count(nid) as a , parted as b from tab_name group by parted ;  # ==> as 代称

对分组里面,使用聚合函数max(),min(),count() ,然后进行筛选,使用having,不是where ;

连表(重要):

select nid from a union select nid from b;   #==> union将多个表字段整合成一个;自动去重

select *  from tab_name1,tab_name2 where tab_name1.count1 = tab_name2.count2 ; #==>连表条件

select *  from tab_name1 left join tab_name2 on tab_name1.count1 = tab_name2.count2 #==>使用join ..on..

select A.columu1 B.columu2  from A,B where A.columu1 = B.columu2

继续阅读