• 第六篇 Mysql数据库


    • mysql相关
      1. 创建数据库&表结构并录入数据(可以自行创造数据)
      create database day27db default charset utf8 collate utf8_general_ci;
      use day27db;
      drop database day27db;
      drop database IF EXISTS day27db;
      
      2.利用导入数据库命令:
      导入:
      mysql -u root -p  day27db < /Users/wupeiqi/day27db.sql
      
      导出:
      # 结构+数据
      mysqldump -u root -p  day27db > /Users/wupeiqi/day27db2.sql
      
      # 结构
      mysqldump -u root -p -d day27db > /Users/wupeiqi/day27db3.sql

      3 创建用户 luffy 并赋予此数据库的所有权限。
      create user 'luffy'@'%' identified by 'root123';
      grant all privileges on day27db.* TO 'luffy'@'%';
      flush privileges;

      ---相关命令:
      1 tasklist |findstr mysql
      2 taskkill /F /PID 10556 #强制杀死
      
      
      ----windows平台mysql密码设置
      #1 关闭mysql
          - tasklist |findstr mysql
          - taskkill /F /PID 10556 #强制杀死
      #2 在cmd中执行:mysqld --skip-grant-tables
      #3 在cmd中执行:mysql
      #4 执行如下sql:
      update mysql.user set authentication_string=password('') where user = 'root';
      flush privileges;
      
      #5 tskill mysqld #或taskkill -f /PID 7832
      #6 重新启动mysql
      
      
      -----配置文件my.ini
      -统一字符编码
      #mysql5.5以上:修改方式有所改动
      [mysqld]
      character-set-server=utf8
      collation-server=utf8_general_ci
      [client]
      default-character-set=utf8
      [mysql]
      default-character-set=utf8
      密码修改-配置文件
       1 权限管理
       2     1、创建账号
       3         # 本地账号
       4         create user 'egon1'@'localhost' identified by '123'; # mysql -uegon1 -p123
       5         # 远程帐号
       6         create user 'egon2'@'192.168.31.10' identified by '123'; # mysql -uegon2 -p123 -h 服务端ip
       7         create user 'egon3'@'192.168.31.%' identified by '123'; # mysql -uegon3 -p123 -h 服务端ip
       8         create user 'egon3'@'%' identified by '123'; # mysql -uegon3 -p123 -h 服务端ip
       9         
      10     2、授权
      11         user:*.*
      12         db:db1.*
      13         tables_priv:db1.t1
      14         columns_priv:id,name
      15         
      16         grant all on *.* to 'egon1'@'localhost';
      17         grant select on *.* to 'egon1'@'localhost';
      18         revoke select on *.* from 'egon1'@'localhost';
      19         
      20         grant select on db1.* to 'egon1'@'localhost';
      21         revoke select on db1.* from 'egon1'@'localhost';
      22         
      23         
      24         grant select on db1.t2 to 'egon1'@'localhost';
      25         revoke select on db1.t2 from 'egon1'@'localhost';
      26         
      27         grant select(id,name),update(age) on db1.t2 to 'egon1'@'localhost';
      权限管理
      1、数据库服务器:运行数据库管理软件的计算机
      
      2、数据库管理软件:mysql,oracle,db2,slqserver
      
      3、库:文件夹
      
      4、表:文件
      
      5、记录:事物一系列典型的特征:egon,male,18,oldgirl
      
      6、数据:描述事物特征的符号
      1数据库相关概念
       1 SQL语句:
       2 
       3 操作文件夹(库)
       4  5         create database db1 charset utf8;
       6  7         show create database db1;
       8         show databases;
       9 10         alter database db1 charset gbk;
      11 12         drop database db1;
      13 
      14 操作文件(表)
      15     切换文件夹:use db1;
      16     查看当前所在文件夹:select database();
      17     
      18 19         create table t1(id int,name char);
      20 21         show create table t1;
      22         show tables;
      23         desc t1;
      24 25         alter table t1 modify name char(6);
      26         alter table t1 change name NAME char(7);
      27 28         drop table t1;
      29 
      30 操作文件内容(记录)
      31 32         insert t1(id,name) values(1,'egon1'),(2,'egon2'),(3,'egon3');
      33 34         select id,name from db1.t1;
      35         select * from db1.t1;
      36 37         update db1.t1 set name='SB';
      38         update db1.t1 set name='ALEX' where id=2;
      39 40         delete from t1 where id=2;
      41         清空表:
      42              delete from t1;
      43             truncate table t1;(同时删除id)
      2 初识SQL语句
       1 1、什么是存储引擎?
       2     存储引擎就是表的类型
       3 
       4 2、查看MySQL支持的存储引擎
       5     show engines;
       6     
       7     
       8 3、指定表类型/存储引擎
       9     create table t1(id int)engine=innodb;
      10     create table t2(id int)engine=memory;
      11     create table t3(id int)engine=blackhole;
      12     create table t4(id int)engine=myisam;
      13 
      14 
      15     insert into t1 values(1);
      16     insert into t2 values(1);
      17     insert into t3 values(1);
      18     insert into t4 values(1);
      3 存储引擎介绍
       1 create table student(
       2     id int,
       3     name char(6),
       4     born_year year,
       5     birth_date date,
       6     class_time time,
       7     reg_time datetime
       8 );
       9 
      10 insert into student values
      11 (1,'egon',now(),now(),now(),now());
      12 
      13 insert into student values
      14 (2,'alex',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12");
      4 日期类型
       1 char:定长
       2 varchar:变长
       3 
       4 #宽度指的是字符的个数
       5 create table t13(name char(5));
       6 create table t14(name varchar(5));
       7 
       8 insert into t13 values('李杰 '); #'李杰   '
       9 insert into t14 values('李杰 '); #'李杰 '
      10 
      11 
      12 select char_length(name) from t13; #5
      13 select char_length(name) from t14; #3
      14 
      15 
      16 select name from t13 where name='李杰';
      17 select name from t13 where name like '李杰';
      18 
      19 
      20 
      21 
      22 name char(5)
      23 egon |alex |wxx  |
      24 
      25 
      26 name varchar(5)
      27 1bytes+egon|1bytes+alex|1bytes+wxx|
      28 4+egon|4+alex|3+wxx|
      5 字符类型
       1 create table consumer(
       2     id int,
       3     name char(16),
       4     sex enum('male','female','other'),
       5     level enum('vip1','vip2','vip3'),
       6     hobbies set('play','music','read','run')
       7 );
       8 
       9 
      10 insert into consumer values
      11 (1,'egon','male','vip2','music,read');
      12 
      13 insert into consumer values
      14 (1,'egon','xxxxx','vip2','music,read');
      6 枚举和集合类型
       1 create table t15(
       2     id int(11) unsigned zerofill
       3 );
       4 
       5 create table t16(
       6     id int,
       7     name char(6),
       8     sex enum('male','female') not null default 'male'
       9 );
      10 
      11 insert into t16(id,name) values(1,'egon');
      7.1 约束条件not null与default
      unique key
      
      单列唯一
          #方式一
          create table department(
              id int unique,
              name char(10) unique
          );
          #方式二:
          create table department(
              id int,
              name char(10),
              unique(id),
              unique(name)
          );
      
      
      
      
          insert into department values
          (1,'IT'),
          (2,'Sale');
      
      
      联合唯一
      create table services(
          id int,
          ip char(15),
          port int,
          unique(id),
          unique(ip,port)
      );
      
      
      
      insert into services values
      (1,'192.168.11.10',80),
      (2,'192.168.11.10',81),
      (3,'192.168.11.13',80);
      
      
      
      
      insert into services values
      (4,'192.168.11.10',80);
      7.2 unique key
      primary key
      约束:not null unique
      存储引擎(innodb):对于innodb存储引擎来说,一张表内必须有一个主键
      
      # 单列主键
      create table t17(
          id int primary key,
          name char(16)
      );
      
      
      
      insert into t17 values
      (1,'egon'),
      (2,'alex');
      
      insert into t17 values
      (2,'wxx');
      
      insert into t17(name) values
      ('wxx');
      
      create table t18(
          id int not null unique,
          name char(16)
      );
      
      
      
      # 复合主键
      create table t19(
          ip char(15),
          port int,
          primary key(ip,port)
      );
      
      
      insert into t19 values
      ('1.1.1.1',80),
      ('1.1.1.1',81);
      7.3 primary-key
        1 auto_increment
        2 
        3 create table t20(
        4     id int primary key auto_increment,
        5     name char(16)
        6 );
        7 
        8 insert into t20(name) values
        9 ('egon'),
       10 ('alex'),
       11 ('wxx');
       12 
       13 
       14 
       15 insert into t20(id,name) values
       16 (7,'yuanhao');
       17 
       18 insert into t20(name) values
       19 ('egon1'),
       20 ('egon2'),
       21 ('egon3');
       22 
       23 
       24 #了解
       25     show variables like 'auto_inc%';
       26 
       27     #步长:
       28     auto_increment_increment默认为1
       29     #起始偏移量
       30     auto_increment_offset默认1
       31     
       32     #设置步长
       33     set session auto_increment_increment=5;
       34     set global auto_increment_increment=5;
       35     
       36     #设置起始偏移量
       37     set global auto_increment_offset=3;
       38     强调:起始偏移量<=步长
       39     
       40     create table t21(
       41         id int primary key auto_increment,
       42         name char(16)
       43     );
       44     
       45     insert into t21(name) values
       46     ('egon'),
       47     ('alex'),
       48     ('wxx'),
       49     ('yxx');
       50     
       51     
       52 
       53 清空表:
       54     delete from t20;
       55     delete from t20 where id = 3;
       56     insert into t20(name) values
       57     ('xxx');
       58     
       59     truncate t20; #应该用它来清空表
       60     
       61     
       62     
       63 foreign key:建立表之间的关系
       64 
       65 #1、建立表关系:
       66     #先建被关联的表,并且保证被关联的字段唯一
       67     create table dep(
       68         id int primary key,
       69         name char(16),
       70         comment char(50)
       71     );
       72 
       73 
       74     #再建立关联的表
       75     create table emp(
       76         id int primary key,
       77         name char(10),
       78         sex enum('male','female'),
       79         dep_id int,
       80         foreign key(dep_id) references dep(id) 
       81         on delete cascade 
       82         on update cascade
       83     );
       84 
       85 #2、插入数据
       86 #先往被关联表插入记录
       87 insert into dep values
       88 (1,"IT","技术能力有限部门"),
       89 (2,"销售","销售能力不足部门"),
       90 (3,"财务","花钱特别多部门");
       91 
       92 #再往关联表插入记录
       93 insert into emp values
       94 (1,'egon','male',1);
       95 
       96 insert into emp values
       97 (2,'alex','male',1),
       98 (3,'wupeiqi','female',2),
       99 (4,'yuanhao','male',3),
      100 (5,'jinximn','male',2);
      101 
      102 
      103 
      104 
      105 delete from emp where dep_id=1;
      106 delete from dep where id=1;
      107 
      108 
      109 
      110 delete from dep where id=3;
      7.4 自增 &外键
       1 两张表之间的关系:
       2     1、多对一
       3         出版社    书(foreign key(press_id) references press(id))
       4     2、多对多
       5         作者       书
       6         egon: 
       7             九阳神功
       8             九阴真经
       9         alex: 
      10             九阳神功
      11             葵花宝典
      12         yuanhao:
      13             独孤九剑
      14             降龙十巴掌
      15             葵花宝典
      16         wpq:
      17             九阳神功
      18             
      19         insert into author2book(author_id,book_id) values
      20         (1,1),
      21         (1,2),
      22         (2,1),
      23         (2,6);
      24             
      25         
      26     3、一对一
      27         customer表       student表
      28
      8 表关系
        1 单表查询
        2 
        3 select distinct 字段1,字段2,字段3 from 库.表 
        4     where 条件
        5     group by 分组条件
        6     having 过滤
        7     order by 排序字段
        8     limit n;
        9     
       10     
       11 #where
       12 select id,name,age from employee where id > 7;
       13     
       14 select name,post,salary from employee where post='teacher' and salary > 8000;
       15 
       16 select name,salary from employee where salary >= 20000 and salary <= 30000;
       17 select name,salary from employee where salary between 20000 and 30000;
       18 
       19 select name,salary from employee where salary < 20000 or salary > 30000;
       20 select name,salary from employee where salary not between 20000 and 30000;
       21 
       22 
       23 select * from employee where age = 73 or age = 81 or age = 28;
       24 select * from employee where age in (73,81,28);
       25 
       26 select * from employee where post_comment is Null;
       27 select * from employee where post_comment is not Null;
       28 
       29 select * from employee where name like "jin%";
       30 select * from employee where name like "jin___";
       31 
       32 
       33 #group by
       34 mysql> set global sql_mode="ONLY_FULL_GROUP_BY"; 
       35 分组之后,只能取分组的字段,以及每个组聚合结果
       36 
       37 select post from employee group by post;
       38 
       39 #聚合函数
       40 max
       41 min
       42 avg
       43 sum
       44 count
       45 
       46 #每个职位有多少个员工
       47 select post,count(id) as emp_count from employee group by post;
       48 select post,max(salary) as emp_count from employee group by post;
       49 select post,min(salary) as emp_count from employee group by post;
       50 select post,avg(salary) as emp_count from employee group by post;
       51 select post,sum(age) as emp_count from employee group by post;
       52 
       53 #没有group by则默认整体算作一组
       54 select max(salary) from employee;
       55 
       56 #group_concat
       57 select post,group_concat(name) from employee group by post;
       58 
       59 
       60 #练习:
       61 select post,group_concat(name) from employee group by post;
       62 
       63 select post,count(id) from employee where age > 50 group by post;
       64 
       65 select sex,count(id) from employee group by sex;
       66 
       67 
       68 select sex,avg(salary) from employee group by sex
       69 
       70 
       71 #having
       72 select post,group_concat(name),count(id) from employee group by post;
       73 
       74 select post,group_concat(name),count(id) from employee group by post having count(id) < 2;
       75 
       76 
       77 select post,avg(salary) from employee group by post having avg(salary) > 10000;
       78 
       79 
       80 #order by
       81 select * from employee order by age asc; #升序
       82 select * from employee order by age desc; #降序
       83 
       84 select * from employee order by age asc,id desc; #先按照age升序排,如果age相同则按照id降序排
       85 
       86 
       87 select distinct post,count(id) as emp_count from employee
       88     where salary > 1000
       89     group by post
       90     having count(id) > 1
       91     order by emp_count desc
       92     ;
       93 
       94 
       95 #limit
       96 select * from employee limit 3;
       97 select * from employee order by salary desc limit 1;
       98 
       99 
      100 select * from employee limit 0,5;
      101 select * from employee limit 5,5;
      102 select * from employee limit 10,5;
      103 select * from employee limit 15,5;
      104 
      105 
      106 #总结:
      107     语法顺序:
      108         select distinct 字段1,字段2,字段3 from 库.表 
      109             where 条件
      110             group by 分组条件
      111             having 过滤
      112             order by 排序字段
      113             limit n;
      114 
      115     执行顺序:
      116 
      117 def from(db,table):
      118         f=open(r'%s\%s' %(db,table))
      119         return f
      120     
      121 def where(condition,f):
      122     for line in f:
      123         if condition:
      124             yield line
      125 
      126 def group(lines):
      127     pass
      128     
      129 def having(group_res):
      130     pass
      131 
      132 def distinct(having_res):
      133     pass
      134 
      135 def order(distinct_res):
      136     pass
      137     
      138 def limit(order_res)
      139     pass
      140     
      141 def select():
      142     f=from('db1','t1')
      143     lines=where('id>3',f)
      144     group_res=group(lines)
      145     having_res=having(group_res)
      146     distinct_res=distinct(having_res)
      147     order_res=order(distinct_res)
      148     res=limit(order_res)
      149     print(res)
      150     return res
      151     
      152 #正则表达式
      153 
      154  like 模糊查询:
      155 select * from employee where name like 'jin%';(# %代表任意多个字符)
      156 select * from employee where name like 'jin_'#'_' 表示任意单个字符)
      157 
      158  regexp 正则匹配
      159 select * from employee where name regexp '^jin';
      160 select * from employee where name regexp '^jin.*(g|n)$';
      161 
      162     
      163
      8.1 单表查询
       1 内连接:只取两张表的共同部分
       2 select * from employee inner join department on employee.dep_id = department.id ;
       3 
       4 左连接:在内连接的基础上保留左表的记录
       5 select * from employee left join department on employee.dep_id = department.id ;
       6 
       7 右连接:在内连接的基础上保留右表的记录
       8 select * from employee right join department on employee.dep_id = department.id ;
       9 
      10 全外连接:在内连接的基础上保留左右两表没有对应关系的记录
      11 select * from employee full join department on employee.dep_id = department.id ;
      12 
      13 
      14 select * from employee left join department on employee.dep_id = department.id
      15 union
      16 select * from employee right join department on employee.dep_id = department.id ;
      8.2 连表查询
       1 #1、无参存储过程
       2     delimiter //
       3     create procedure p1()
       4     BEGIN
       5         select * from db7.teacher;
       6     END //
       7     delimiter ;
       8 
       9 
      10     # MySQL中调用
      11     call p1();
      12 
      13 
      14     # Python中调用
      15     cursor.callproc('p1')
      16     
      17     
      18 #2、有参存储过程
      19     delimiter //
      20     create procedure p2(in n1 int,in n2 int,out res int)
      21     BEGIN
      22         select * from db7.teacher where tid > n1 and tid < n2;
      23         set res = 1;
      24     END //
      25     delimiter ;
      26 
      27 
      28     # MySQL中调用
      29     set @x=0
      30     call p2(2,4,@x);
      31     select @x;
      32 
      33     # Python中调用
      34     cursor.callproc('p2',(2,4,0))# @_p2_0=2,@_p2_1=4,@_p2_2=0
      35     cursor.execute('select @_p3_2')
      36     cursor.fetchone()
      37     
      38     
      39 
      40     
      41 应用程序与数据库结合使用
      42 方式一:
      43     Python:调用存储过程
      44     MySQL:编写存储过程
      45 
      46     
      47 方式二:
      48     Python:编写纯生SQL
      49     MySQL:
      50     
      51 方式三:
      52     Python:ORM->纯生SQL
      53     MySQL:
      54 
      55 
      56 
      57
      存储过程
       1 CREATE TABLE blog (
       2     id INT PRIMARY KEY auto_increment,
       3     NAME CHAR (32),
       4     sub_time datetime
       5 );
       6 
       7 INSERT INTO blog (NAME, sub_time)
       8 VALUES
       9     ('第1篇','2015-03-01 11:31:21'),
      10     ('第2篇','2015-03-11 16:31:21'),
      11     ('第3篇','2016-07-01 10:21:31'),
      12     ('第4篇','2016-07-22 09:23:21'),
      13     ('第5篇','2016-07-23 10:11:11'),
      14     ('第6篇','2016-07-25 11:21:31'),
      15     ('第7篇','2017-03-01 15:33:21'),
      16     ('第8篇','2017-03-01 17:32:21'),
      17     ('第9篇','2017-03-01 18:31:21');
      18     
      19     
      20     
      21 select  date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m')
      函数相关(如date_format)
       1 where字句中可以使用:
       2 
       3 1比较运算符:><>= <= <> !=
       4 2between 80 and 100 值在80到100之间
       5 3in(80,90,100) 值是80或90或100
       6 4 like 'egon%'
       7    pattern可以是%或_,
       8    %表示任意多字符
       9    _表示一个字符
      10 5逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not
      11 
      12 #1:单条件查询
      13     SELECT name FROM employee
      14         WHERE post='sale';
      15 
      16 #2:多条件查询
      17     SELECT name,salary FROM employee
      18         WHERE post='teacher' AND salary>10000;
      19 
      20 #3:关键字BETWEEN AND
      21     SELECT name,salary FROM employee 
      22         WHERE salary BETWEEN 10000 AND 20000;
      23 
      24     SELECT name,salary FROM employee 
      25         WHERE salary NOT BETWEEN 10000 AND 20000;
      26 
      27 #4:关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)
      28     SELECT name,post_comment FROM employee 
      29         WHERE post_comment IS NULL;
      30 
      31     SELECT name,post_comment FROM employee 
      32         WHERE post_comment IS NOT NULL;
      33 
      34     SELECT name,post_comment FROM employee 
      35         WHERE post_comment=''; 注意''是空字符串,不是null
      36     ps:
      37         执行
      38         update employee set post_comment='' where id=2;
      39         再用上条查看,就会有结果了
      40 
      41 #5:关键字IN集合查询
      42     SELECT name,salary FROM employee 
      43         WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;
      44 
      45     SELECT name,salary FROM employee 
      46         WHERE salary IN (3000,3500,4000,9000) ;
      47 
      48     SELECT name,salary FROM employee 
      49         WHERE salary NOT IN (3000,3500,4000,9000) ;
      50 
      51 #6:关键字LIKE模糊查询
      52     通配符’%53     SELECT * FROM employee 
      54             WHERE name LIKE 'eg%';
      55 
      56     通配符’_’
      57     SELECT * FROM employee 
      58             WHERE name LIKE 'al__';
      59 1. 查看岗位是teacher的员工姓名、年龄
      60 2. 查看岗位是teacher且年龄大于30岁的员工姓名、年龄
      61 3. 查看岗位是teacher且薪资在9000-1000范围内的员工姓名、年龄、薪资
      62 4. 查看岗位描述不为NULL的员工信息
      63 5. 查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资
      64 6. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
      65 7. 查看岗位是teacher且名字是jin开头的员工姓名、年薪
      66 select name,age from employee where post = 'teacher';
      67 select name,age from employee where post='teacher' and age > 30; 
      68 select name,age,salary from employee where post='teacher' and salary between 9000 and 10000;
      69 select * from employee where post_comment is not null;
      70 select name,age,salary from employee where post='teacher' and salary in (10000,9000,30000);
      71 select name,age,salary from employee where post='teacher' and salary not in (10000,9000,30000);
      72 select name,salary*12 from employee where post='teacher' and name like 'jin%';
      where约束查询(in,between,like等))
    • pymysql
       1 #pip3 install pymysql
       2 import pymysql
       3 
       4 user=input('user>>: ').strip()
       5 pwd=input('password>>: ').strip()
       6 
       7 # 建立链接
       8 conn=pymysql.connect(
       9     host='192.168.10.15',
      10     port=3306,
      11     user='root',
      12     password='123',
      13     db='db9',
      14     charset='utf8'
      15 )
      16 
      17 # 拿到游标
      18 cursor=conn.cursor()
      19 
      20 # 执行sql语句
      21 
      22 # sql='select * from userinfo where user = "%s" and pwd="%s"' %(user,pwd)
      23 # print(sql)
      24 
      25 sql='select * from userinfo where user = %s and pwd=%s'
      26 rows=cursor.execute(sql,(user,pwd))
      27 
      28 cursor.close()
      29 conn.close()
      30 
      31 # 进行判断
      32 if rows:
      33     print('登录成功')
      34 else:
      35     print('登录失败')
      pymysql基本使用
       1 #1、增删改
       2 import pymysql
       3 
       4 # 建立链接
       5 conn=pymysql.connect(
       6     host='127.0.0.1',
       7     port=3306,
       8     user='root',
       9     password='',
      10     db='text1',
      11     charset='utf8'
      12 )
      13 
      14 # 拿游标
      15 cursor=conn.cursor()
      16 
      17 # 执行sql
      18 # 增、删、改
      19 
      20 
      21 ##################    1 插入数据     ###########
      22 # 单条插入
      23 # sql='insert into t1(user,pwd) values(%s,%s)'
      24 # # rows=cursor.execute(sql,('wxx','123')) #
      25 # rows = cursor.execute('insert into t1(user,pwd) values(%(user)s, %(pwd)s)',{'user':'hah','pwd':'123'})
      26 # print(rows)
      27 #
      28 # # 批量插入
      29 # rows=cursor.executemany(sql,[('egon3','123'),('egon4','111'),('egon5','2222')]) # 批量插入
      30 # print(cursor.lastrowid)
      31 
      32 ##################    2 修改数据     ###########
      33 # sql='update t1 set user = %s where user ="wxx"'
      34 # rows = cursor.execute(sql,("wh"))
      35 # print(rows)
      36 
      37 
      38 ##################    3 删除数据    ###########
      39 # sql='delete from t1 where user like "%alin%"'
      40 # rows = cursor.execute(sql)
      41 # print(rows)
      42 
      43 # conn.commit()
      44 
      45 # # 关闭
      46 # cursor.close()
      47 # conn.close()
      pymsql 增,删,改
       1 ##################    4 查询数据    ###########
       2 
       3 
       4 # import pymysql
       5 #
       6 # # 建立链接
       7 # conn=pymysql.connect(
       8 #     host='192.168.10.15',
       9 #     port=3306,
      10 #     user='root',
      11 #     password='123',
      12 #     db='db9',
      13 #     charset='utf8'
      14 # )
      15 
      16 # 拿游标
      17 # cursor=conn.cursor(pymysql.cursors.DictCursor)
      18 
      19 # 执行sql
      20 # 查询
      21 # rows=cursor.execute('select * from t1;')
      22 # print(rows)
      23 # print(cursor.fetchone())
      24 # print(cursor.fetchone())
      25 
      26 
      27 
      28 # print(cursor.fetchmany(2))
      29 
      30 # print(cursor.fetchall())
      31 # print(cursor.fetchall())
      32 
      33 
      34 
      35 # cursor.scroll(3,mode='absolute') # 相对绝对位置移动
      36 # print(cursor.fetchone())
      37 # cursor.scroll(2,mode='relative') # 相对当前位置移动
      38 # print(cursor.fetchone())
      39 
      40 #
      41 
      42 # 关闭
      43 # cursor.close()
      44 # conn.close()
      pymsql 查询
      #1、增删改
      import pymysql
      
      # 建立链接
      conn=pymysql.connect(
          host='192.168.10.15',
          port=3306,
          user='root',
          password='123',
          db='db7',
          charset='utf8'
      )
      
      # 拿游标
      cursor=conn.cursor()
      
      # 执行sql
      # cursor.callproc('p1')
      # print(cursor.fetchall())
      
      cursor.callproc('p2',(2,4,0))
      # print(cursor.fetchall())
      
      cursor.execute('select @_p2_2')
      print(cursor.fetchone())
      
      # 关闭
      cursor.close()
      conn.close()
      存储过程的执行

       

    • 事务  
      import pymysql
      
      conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='root123', charset="utf8", db='userdb')
      cursor = conn.cursor()
      
      # 开启事务
      conn.begin()
      
      try:
          cursor.execute("update users set amount=1 where id=1")
          int('asdf')
          cursor.execute("update tran set amount=2 where id=2")
      except Exception as e:
          # 回滚
          print("回滚")
          conn.rollback()
      else:
          # 提交
          print("提交")
          conn.commit()
      
      cursor.close()
      conn.close()
      事务
    • 排他锁
      排它锁( for update),加锁之后,其他事务不可以读写
      A: 访问页面查看商品剩余 100
      B: 访问页面查看商品剩余 100
      
      此时 A、B 同时下单,那么他们同时执行SQL:
          update goods set count=count-1 where id=3
      由于Innodb引擎内部会加锁,所以他们两个即使同一时刻执行,内部也会排序逐步执行。
      
      
      但是,当商品剩余 1个时,就需要注意了。
      A: 访问页面查看商品剩余 1
      B: 访问页面查看商品剩余 1
      
      此时 A、B 同时下单,那么他们同时执行SQL:
          update goods set count=count-1 where id=3
      这样剩余数量就会出现 -1,很显然这是不正确的,所以应该怎么办呢?
      
      
      这种情况下,可以利用 排它锁,在更新之前先查询剩余数量,只有数量 >0 才可以购买,所以,下单时应该执行:
          begin; -- start transaction;
          select count from goods where id=3 for update;
          -- 获取个数进行判断
          if 个数>0:
              update goods set count=count-1 where id=3;
          else:
              -- 已售罄
          commit;
      应用场景:总共100件商品,每次购买一件需要让商品个数减1
      import pymysql
      import threading
      
      
      def task():
          conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='root123', charset="utf8", db='userdb')
          cursor = conn.cursor(pymysql.cursors.DictCursor)
          # cursor = conn.cursor()
          
          # 开启事务
          conn.begin()
      
          cursor.execute("select id,age from tran where id=2 for update")
          # fetchall      ( {"id":1,"age":10},{"id":2,"age":10}, )   ((1,10),(2,10))
          # {"id":1,"age":10}   (1,10)
          result = cursor.fetchone()
          current_age = result['age']
          
          if current_age > 0:
              cursor.execute("update tran set age=age-1 where id=2")
          else:
              print("已售罄")
      
          conn.commit()
      
          cursor.close()
          conn.close()
      
      
      def run():
          for i in range(5):
              t = threading.Thread(target=task)
              t.start()
      
      
      if __name__ == '__main__':
          run()
      排他锁(for update)
    • SQL工具类
      基于数据库连接池开发一个公共的SQL操作类,方便以后操作数据库 
      # db.py
      # 单例与方法
      
      import pymysql
      from dbutils.pooled_db import PooledDB
      
      
      class DBHelper(object):
      
          def __init__(self):
              # TODO 此处配置,可以去配置文件中读取。
              self.pool = PooledDB(
                  creator=pymysql,  # 使用链接数据库的模块
                  maxconnections=5,  # 连接池允许的最大连接数,0和None表示不限制连接数
                  mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
                  maxcached=3,  # 链接池中最多闲置的链接,0和None不限制
                  blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
                  setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
                  ping=0,
                  # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
                  host='127.0.0.1',
                  port=3306,
                  user='root',
                  password='root123',
                  database='userdb',
                  charset='utf8'
              )
      
          def get_conn_cursor(self):
              conn = self.pool.connection()
              cursor = conn.cursor(pymysql.cursors.DictCursor)
              return conn, cursor
      
          def close_conn_cursor(self, *args):
              for item in args:
                  item.close()
      
          def exec(self, sql, **kwargs):
              conn, cursor = self.get_conn_cursor()
      
              cursor.execute(sql, kwargs)
              conn.commit()
      
              self.close_conn_cursor(conn, cursor)
      
          def fetch_one(self, sql, **kwargs):
              conn, cursor = self.get_conn_cursor()
      
              cursor.execute(sql, kwargs)
              result = cursor.fetchone()
      
              self.close_conn_cursor(conn, cursor)
              return result
      
          def fetch_all(self, sql, **kwargs):
              conn, cursor = self.get_conn_cursor()
      
              cursor.execute(sql, kwargs)
              result = cursor.fetchall()
      
              self.close_conn_cursor(conn, cursor)
      
              return result
      
      
      db = DBHelper()
      SQL操作类(基于数据库连接池)
      from db import db
      
      db.exec("insert into d1(name) values(%(name)s)", name="华王666")
      
      ret = db.fetch_one("select * from d1")
      print(ret)
      
      ret = db.fetch_one("select * from d1 where id=%(nid)s", nid=3)
      print(ret)
      
      ret = db.fetch_all("select * from d1")
      print(ret)
      
      ret = db.fetch_all("select * from d1 where id>%(nid)s", nid=2)
      print(ret)
    • 操作表(utils)

      #操作表
      #1、自行创建测试数据;
      #班级表:class
      create table class(
      cid int primary key auto_increment,
      caption char(5),
      grade_id int
      );
      insert into class values
      (1,'一年一班',1),
      (2,'二年一班',2),
      (3,'三年二班',3);
      
      #2、查询学生总人数;
          select count(sid) as total_sid from student;
          
      #3、查询“生物”课程和“物理”课程成绩都及格的学生id和姓名;
          #成绩表与课程表连表-一学生分组-找出条件
      select sid,sname from 
          student where sid in 
              (select student_id 
              from score inner join course  #连表
                  on score.course_id=course.cid
                  where score>=60 
                  and cname ='生物' or cname ='物理'
              group by # 学生id分组
                  score.student_id
              having
                  count(course_id)=2);
                  
      
      #4、查询每个年级的班级数,取出班级数最多的前三个年级;
          select gname,count(gname) from 
          class inner join class_grade on class.grade_id=class_grade.gid
              group by 
                  gname
                  order by count(gname)desc
                  limit(3);
          
      
      #5、查询平均成绩最高和最低的学生的id和姓名以及平均成绩;
      select 
          sid,
          sname,
          t1.avg_score
      from
          student
      inner join(
          select
              student_id,
              avg(score)as avg_score
          from
              score
          group by
              student_id
          having
              avg(score) in(
                  (select avg(score)as low_score from score group by student_id order by avg(score) limit 1),
                  (select avg(score)as high_score from score group by student_id order by avg(score) desc limit 1))
              )as t1
      on
          student.sid=t1.student_id;
          
      
      #6、查询每个年级的学生人数;
      # 学生与班级连表-grade_id分组-统计人数
      
      select grade_id,count(sid)as total_student
      from
      (select
          class.grade_id,student.sid
      from
          student
      inner join 
          class
      on
          student.class_id=class.cid) as t1
      group by 
          t1.grade_id;
          
          
      
      #7、查询每位学生的学号,姓名,选课数,平均成绩;
      select
          sid,
          sname,
          t1.total_course,
          t1.avg_score
      from
          student
      left join(
          select
              student_id,
              count(course_id)as total_course,
              avg(score)as avg_score
          from
              score
          group by
              student_id
          )as t1
      on
      student.sid=t1.student_id;
      
      #8、查询学生编号为“2”的学生的姓名、该学生成绩最高的课程名、成绩最低的课程名及分数;
      select
          sid,
          sname,
          t1.course_id,
          t1.score
      from
          student
      inner join(
          select
              student_id,
              course_id,
              score
          from
              score
          where
              score in(
                  (select score from score where student_id=2 order by score desc limit 1),
                  (select score from score where student_id=2 order by score limit 1 )
                  )
              )as t1
      on
          student.sid=t1.student_id;
       
      #9、查询姓“李”的老师的个数和所带班级数;
      select
          count(t1.tid)as total_li,
          count(teach2cls.cid)as total_class
      from
          teach2cls
      inner join(
          select
              tid
          from
              teacher
          where
              tname like "李%"
          )as t1
      on
          teach2cls.tid=t1.tid
      
      #10、查询班级数小于5的年级id和年级名;
      select 
          gid,
          gname
      from
          class_grade
      where 
          gid
      in
          (select #年纪id与对应班级数的表
              grade_id
          from
              class 
          group by
              grade_id
          having
              count(cid)<5);
          
      
      
      #11、查询班级信息,包括班级id、班级名称、年级、年级级别(12为低年级,34为中年级,56为高年级)
          #班级id    班级名称    年级  年级级别
              #1     一年一班    一年级    低
              
          #班级表与年纪表连表--加入级别
          
      select
          class.cid as '班级id',
          class.caption as '班级名称',
          class_grade.gname as '年级',
          case when class_grade.gid between 1 and 2 then ''
          when class_grade.gid between 3 and 4 then ''
          when class_grade.gid between 5 and 6 then '' else 0 end as '年级级别'
      from
          class,
          class_grade
      where
          class.grade_id = class_grade.gid;
          
      #12、查询学过“张三”老师2门课以上的同学的学号、姓名;
          # 课程表与老师表连表--选出张三老师的课程-到成绩表以学生分类-统计符合条件学生
      
      select
          student_id
      from
          score
      where
          course_id
      in
          (select
              course.cid
          from
              course
          inner join
              teacher
          on
              course.teacher_id=teacher.tid
          where 
              teacher.tname='张三')
      group by
          student_id
      having
          count(course_id)>=2;
          
          
      #13、查询教授课程超过2门的老师的id和姓名;
      
      select 
          tid,
          tname
      from
          teacher
      where 
          tid 
      in 
          (select 
              teacher_id
          from
              course
          group by 
              teacher_id
          having
              count(cid)>2
          );
      
      #14、查询学过编号“1”课程和编号“2”课程的同学的学号、姓名;
      select 
          sid,sname
      from
          student
      where 
          sid
      in
          (select 
              student_id 
          from 
              score
          where 
              course_id
          in 
              ('1','2')
          group by
              student_id
          having
              count(course_id)=2);
      
      #15、查询没有带过高年级的老师id和姓名;
      
      select
          tid,
          tname
      from
          teacher
      where 
          tid
      in
          (select
              tid
          from
              teach2cls
          where
              cid
          in
              (select
                  cid 
              from
                  class
              where
                  grade_id<3));
          
      
      #16、查询学过“张三”老师所教的所有课的同学的学号、姓名;
      
      select
          sid,
          sname
      from
          student
      where sid in (
          select distinct student_id from score where course_id in (
              select cid from course where teacher_id in(
                  select tid from teacher where tname='张三'
                  )
              )
          );
      #17、查询带过超过2个班级的老师的id和姓名;
      select
          tid,
          tname
      from
          teacher
      where tid in (
          select
              tid
          from
              teach2cls
          group by
              tid
          having
              count(cid)>2
      );
      #18、查询课程编号“2”的成绩比课程编号“1”课程低的所有同学的学号、姓名;
          
      select
        sid,
        sname
      from 
          student
      where sid in (
          select s1.student_id
          from score as s1 inner join score as s2 on s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 2
          where s1.score < s2.score);
      
      #19、查询所带班级数最多的老师id和姓名;
      
      select
          tid,
          tname
      from
          teacher
      where
          tid in (
              select
                  tid
              from
                  teach2cls
              group by
                  tid
              having
                  count(cid)=(
                      select
                          count(cid)
                      from
                          teach2cls
                      group by
                          tid
                      order by
                          count(cid) desc
                      limit 1
                  )
          );
      #20、查询有课程成绩小于60分的同学的学号、姓名;
      select
          sid,
          sname
      from
          student
      where
          sid in (
              select
                  student_id
              from
                  score
              where
                  score<60
          );
       
      #21、查询没有学全所有课的同学的学号、姓名;
      
      select 
          sid,
          sname
      from
          student
      where
          sid
      not in
          (select 
              student_id
          from
              score
          group by
              student_id
          having
              count(course_id)=(select count(cid) from course)
              );
      
      #22、查询至少有一门课与学号为“1”的同学所学相同的同学的学号和姓名;
      select
          sid,sname
      from
          student
      where
          sid in (
              select
                  distinct student_id
              from
                  score
              where
                  course_id in(
                      select
                          course_id
                      from
                          score
                      where
                          student_id =1
                  )
          )
          and sid !=1;
      
      #23、查询至少学过学号为“1”同学所选课程中任意一门课的其他同学学号和姓名;
      select
          sid,sname
      from
          student
      where
          sid in (
              select
                  distinct student_id
              from
                  score
              where
                  course_id in(
                      select
                          course_id
                      from
                          score
                      where
                          student_id =1
                  )
          )
          and sid !=1;
      
      #24、查询和“2”号同学学习的课程完全相同的其他同学的学号和姓名;
      
      select
          sid,
          sname
      from
          student
      where sid in (
          select student_id from score,
          (select course_id from score where student_id=2)as t1
          where score.course_id = t1.course_id and score.student_id !=2 group by score.student_id
          having count(score.course_id)=(select count(course_id)from score where student_id=2)
      );
      
      
      #25、删除学习“张三”老师课的score表记录;
      
      delete from score where course_id in (
          select cid from course where teacher_id =(
              select tid from teacher where tname='张三')
      );
      
      #26、向score表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“2”课程的同学学号;②插入“2”号课程的平均成绩;
      insert score(student_id,course_id,score)
          select t1.sid,2,t2.avg_score from(
          (select sid from student where sid not in (select student_id from score where course_id = 2)) as t1,
          (select avg(score)as avg_score from score where course_id = 2) as t2);
          
      #27、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示:学生ID,语文,数学,英语,课程数和平均分;
      
      select
          student_id,
          (select score from score where course_id =(select cid from course where cname='语文') and score.student_id =s1.student_id ) as '语文',
          (select score from score where course_id =(select cid from course where cname='数学') and score.student_id =s1.student_id ) as '数学',
          (select score from score where course_id =(select cid from course where cname='英语') and score.student_id =s1.student_id ) as '英语',
          count(course_id) as '有效课程数',
          avg(score) as '有效平均分'
      from
          score as s1
      group by
          student_id
      order by
          avg(score);
      
      
      #28、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
      
      select
          course_id as id,
          max(score.score) as '最高分',
          min(score.score) as '最低分'
      from
          course
      left join score
      on score.course_id=course.cid 
      group by course_id;
      
      #29、按各科平均成绩从低到高和及格率的百分数从高到低顺序;
      select course_id,
          avg(score) as avg_score,
          sum(case when score.score >= 60 then 1 else 0 end) / count(sid) * 100 as percent
      from
          score
      group by
          course_id
      order by
          avg(score) asc,percent desc;
      #30、课程平均分从高到低显示(现实任课老师);
      select
          t1.cid,
          t1.tname,
          t2.avg_score
      from(
          select
              teacher.tid as tid,
              teacher.tname as tname,
              course.cid as cid
          from
              teacher
          inner join
              course
          on teacher.tid = teacher_id
          )as t1
      inner join
          (select course_id,avg(score)as avg_score from score group by course_id )as t2
      on
          t1.cid=t2.course_id
      order by
          avg_score desc;
      
      #31、查询各科成绩前三名的记录(不考虑成绩并列情况) ;
      select
        student_id,
        score,
        course_id
      from score r1
      where (SELECT count(1)
             from (select distinct
                     score,
                     course_id
                   from score) r2
             where r2.course_id = r1.course_id AND r2.score > r1.score) <= 2
      order by course_id, score DESC;
       
      #32、查询每门课程被选修的学生数;
      select
          course_id,
          count(student_id)
      from
          score
      group by
          course_id;
      
      #33、查询选修了2门以上课程的全部学生的学号和姓名;
      elect
          sid,
          sname
      from
          student
      where sid in(
          select
              student_id
          from
              score
          group by
              student_id
          having
              count(course_id)>2);
      
      #34、查询男生、女生的人数,按倒序排列;
      select
          gender,
          count(sid)
      from
          student
      group by
          gender
      order by   
          count(sid) desc;
      
      #35、查询姓“张”的学生名单;
      select
          *
      from
          student
      where
          sname like "张%";
      #36、查询同名同姓学生名单,并统计同名人数;
      select
          sname,
          count(sid)
      from
          student
      group by
          sname
      having
          count(sid)>1;
      #37、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
      select
          course_id,
          avg(score)
      from
          score
      group by
          course_id
      order by
          avg(score),
          course_id desc;
      #38、查询课程名称为“数学”,且分数低于60的学生姓名和分数;
      select
          student.sname,
          t1.score
      from
          student
      inner join  (
          select
              student_id,
              score
          from
              score
          where score.score<60 and course_id in (
              select
                  cid
              from
                  course
              where cname='数学'
          )
      )as t1
      on 
          t1.student_id=student.sid;
      #39、查询课程编号为“3”且课程成绩在80分以上的学生的学号和姓名;
      select
          sid,
          sname
      from
          student
      where sid in(
          select
              student_id
          from
              score
          where
          course_id=3 and score>80
      );
      #41、查询选修“王五”老师所授课程的学生中,成绩最高和最低的学生姓名及其成绩;
      select
          s1.student_id,
          low_score,
          s2.student_id,
          high_score
      from(
          select
              tid,
              student_id,
              score as low_score
          from
              (select student_id,cid,cname,score,tid
              from score
              inner join
                  (select tid,tname,cid,cname from teacher inner join course on teacher.tid=course.teacher_id where tname='王五')as t1
              on score.course_id=t1.cid)as t2 order by score limit 1) as s1
          inner join (
              select tid,student_id,score as high_score from
                  (select student_id,cid,cname,score,tid
                  from score
                  inner join
                      (select tid,tname,cid,cname from teacher
                      inner join
                          course
                      on teacher.tid=course.teacher_id where tname='王五')as t1
                  on score.course_id=t1.cid)as t2 order by score desc limit 1) as s2
          on s1.tid=s2.tid;
      #42、查询各个课程及相应的选修人数;
      select
          course_id ,
          count(student_id)
      from
          score
      group by
          course_id;
          
      #43、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
      select distinct
          s1.course_id,
          s1.student_id,
          s1.score,
          s2.course_id,
          s2.student_id,
          s2.score
      from
          score as s1,
          score as s2
      where
      s1.score = s2.score and s1.course_id != s2.course_id;
      #44、查询每门课程成绩最好的前两名学生id和姓名;
      select student.sid,student.sname,course.cname, score.score
          from score
      inner join (
          select course_id, score, ranking
              from (
                   select a.course_id, a.score, count(1) as ranking
                      from
                          (select course_id, score from score group by course_id, score order by course_id, score desc)as a
                      inner join
                          (select course_id, score from score group by course_id, score order by course_id, score desc)as b
                      on a.course_id = b.course_id and a.score <= b.score group by course_id, score
              ) as t1
              where ranking in (1, 2) order by course_id, ranking)as s1
      on score.course_id = s1.course_id and score.score = s1.score
      inner join student
          on score.student_id = student.sid
      inner join course
          on score.course_id = course.cid;
          
      #45、检索至少选修两门课程的学生学号;
      select
          student_id
      from
          score
      group by
          student_id
      having
          count(course_id)>=2;
          
      #46、查询没有学生选修的课程的课程号和课程名;
      select
          course.cid,
          course.cname
      from
          course
      left join
          score
      on
          course.cid=score.course_id
      where
          score.student_id is null;
          
      #47、查询没带过任何班级的老师id和姓名;
      select
          teacher.tid,
          tname
      from
          teacher
      left join
          teach2cls
      on
          teacher.tid=teach2cls.tid
      where
          teach2cls.tcid is null;
          
      #48、查询有两门以上课程超过80分的学生id及其平均成绩;
      select
          student_id,
          avg(score)
      from
          score
      where
          score>80
      group by
          student_id
      having
          count(course_id)>2;
          
      #49、检索“3”课程分数小于60,按分数降序排列的同学学号;
      select
          student_id,
          score
      from
          score
      where
          score<60 and course_id=3
      order by
          score desc;
          
      #50、删除编号为“2”的同学的“1”课程的成绩;
      delete from
          score 
       where
       student_id='2' and course_id='1';
       
      #51、查询同时选修了物理课和生物课的学生id和姓名
      
      
      select
          student.sid,
          student.sname
      from
          student
      where sid in (
              select
                  student_id
              from
                  score
              where
                  course_id IN (
                      select
                          cid
                      from
                          course
                      where cname = '物理' or cname = '生物'
                  )
              group by
                  student_id
              having
                  count(course_id) = 2
          );
      原生sql示例
       1 """
       2 
       3 使用
       4 from mysql_utils.sql import SQLHelper
       5 
       6 sql ="select * from 36kr"
       7 print(SQLHelper.fetch_one(sql))
       8 print(SQLHelper.fetch_all(sql))
       9 
      10 # print(SQLHelper.fetchdic_one_dict(sql,{}))
      11 # print(SQLHelper.fetch_all_list_dict(sql,{}))
      12 """
      13 
      14 import pymysql
      15 
      16 
      17 class SQLHelper(object):
      18 
      19     @staticmethod
      20     def open(cursor):
      21         conn = pymysql.connect(
      22             host='127.0.0.1',
      23             port=3306,
      24             user='root',
      25             password='',
      26             db='new_source',
      27             charset='utf8'
      28         )
      29         cursor = conn.cursor(cursor=cursor)
      30         return conn,cursor
      31 
      32     @staticmethod
      33     def close(conn,cursor):
      34         conn.commit()
      35         cursor.close()
      36         conn.close()
      37 
      38     @classmethod
      39     def fetch_one(cls, sql, cursor=None):
      40         """
      41         默认返回一个元组
      42         :param sql:
      43         :param args:
      44         :param cursor:
      45         :return:
      46         """
      47         conn, cursor = cls.open(cursor)
      48         cursor.execute(sql)
      49         obj = cursor.fetchone()
      50         cls.close(conn, cursor)
      51         return obj
      52 
      53     @classmethod
      54     def fetch_all(cls, sql, cursor=None):
      55         conn, cursor = cls.open(cursor)
      56         cursor.execute(sql)
      57         obj = cursor.fetchall()
      58         cls.close(conn, cursor)
      59         return obj
      60 
      61     @classmethod
      62     def fetchdic_one_dict(cls, sql, args, cursor=pymysql.cursors.DictCursor):
      63         """
      64         默认返回一个字典
      65         :param sql:
      66         :param args:
      67         :param cursor:
      68         :return:{'id': 4, 'name': 'egon3', 'count': 123}
      69         """
      70         conn, cursor = cls.open(cursor)
      71         cursor.execute(sql, args)
      72         obj = cursor.fetchone()
      73         cls.close(conn, cursor)
      74         return obj
      75     @classmethod
      76     def fetch_all_list_dict(cls,sql, args,cursor =pymysql.cursors.DictCursor):
      77         """
      78         返回一个列表,列表元素为字典
      79         :param sql:
      80         :param args:
      81         :param cursor:
      82         :return: #[{'id': 4, 'name': 'egon3', 'count': 123}, {'id': 5, 'name': 'egon4', 'count': 111}]
      83         """
      84         conn, cursor = cls.open(cursor)
      85         cursor.execute(sql, args)
      86         obj = cursor.fetchall()
      87         cls.close(conn, cursor)
      88         return obj
      SQLHelper
        1 #coding:utf-8
        2 import MySQLdb
        3 import json
        4 import time
        5 
        6 
        7 db = ""
        8 cursor = ""
        9 def db_init():
       10     global db
       11     global cursor
       12     # db = MySQLdb.connect("", "c396313051","123456ok","news", charset="utf8mb4")
       13     db = MySQLdb.connect("", "root","","news_crawl",port=22936,charset="utf8mb4")
       14     cursor = db.cursor()
       15     # 使用cursor()方法获取操作游标 
       16     # print("Connection is successful!")
       17 
       18 def db_close():
       19     db.close()
       20 
       21 def db_commit():
       22     db.commit()
       23 
       24 def get_unupdate_count():
       25     db_init()
       26     sql = "SELECT COUNT(*) FROM news_detail WHERE flag_content_update = '0' "
       27     try:
       28         cursor.execute(sql)
       29         result = cursor.fetchall()
       30         # print("result", result)
       31         print("result", result[0][0])
       32         return result
       33     except Exception as e:
       34         print("ERROR", e)
       35 
       36 def get_unupdate_news():
       37     db_init()
       38     sql = "SELECT * FROM news_detail WHERE flag_content_update = '0' AND web_source = 'techweb'  ORDER BY release_time DESC LIMIT 5000"
       39     try:
       40         cursor.execute(sql)
       41         result = cursor.fetchall()
       42         # print("result", result)
       43         news_list = []
       44         for row in result:
       45             news_id = row[6]
       46             news_url = row[1]
       47             news_web_source = row[5]
       48             news_list.append({
       49                 "id": news_id,
       50                 "url": news_url,
       51                 "web_source": news_web_source
       52             })
       53         print("news_list", news_list)
       54         return news_list
       55     except Exception as e:
       56         print("ERROR", e)
       57 
       58 def check_news(title, web_source):
       59     db_init()
       60     sql = "SELECT COUNT(*) FROM news_detail WHERE title = '%s' AND web_source = '%s'" %(title, web_source)
       61     try:
       62         cursor.execute(sql)
       63         result = cursor.fetchall()
       64         # print("result", result)
       65         print("result", result[0][0])
       66         return result[0][0]
       67     except Exception as e:
       68         print("ERROR", e)
       69 
       70 def update_news_content(news_id, news_content):
       71     if news_content != None:
       72         db_init()
       73         sql = "UPDATE news_detail SET content = '%s', flag_content_update = '1' WHERE id = '%s'" % (news_content, news_id)
       74         try:
       75             cursor.execute(sql)
       76             db.commit()
       77             print("content已更新!", news_id)
       78         except Exception as e:
       79             print("ERROR", e)
       80             db.rollback()
       81 
       82 def get_latest_data_50(web_source):
       83     db_init()
       84     sql = "SELECT * FROM news_detail WHERE web_source = '%s' ORDER BY release_time DESC LIMIT 50" % (web_source)
       85     try:
       86         cursor.execute(sql)
       87         result = cursor.fetchall()
       88         # print("result", result)
       89         title_list = []
       90         for row in result:
       91             title = row[0]
       92             title_list.append(title)
       93         # print("title_list", title_list)
       94         return title_list
       95     except Exception as e:
       96         print("ERROR", e)
       97 
       98 def get_latest_data(web_source):
       99     db_init()
      100     sql = "SELECT * FROM news_detail WHERE web_source = '%s' ORDER BY release_time DESC LIMIT 10" % (web_source)
      101     try:
      102         cursor.execute(sql)
      103         result = cursor.fetchall()
      104         # print("result", result)
      105         title_list = []
      106         for row in result:
      107             title = row[0]
      108             title_list.append(title)
      109         # print("title_list", title_list)
      110         return title_list
      111     except Exception as e:
      112         print("ERROR", e)
      113 
      114 def getData(source_name_val):
      115     db_init()
      116     # cursor = db.cursor()
      117     sql = "SELECT * FROM source_info WHERE source_name = '%s'" % (source_name_val)
      118     try:
      119         cursor.execute(sql)
      120         results = cursor.fetchall()
      121         for row in results:
      122             source_name = row[0]
      123             update_time = row[1]
      124             latest_news = row[2]
      125             # print("source_name", source_name)
      126             # print("update_time", update_time)
      127             # print("latest_news", json.loads(latest_news))
      128             return latest_news
      129     except Exception as e:
      130         print("ERROR",e)
      131 
      132     # 关闭数据库连接
      133     db.close()
      134 '''
      135 {"title": "寻电之路2:海外合资品牌的全面反攻", "url": "https://www.autotimes.com.cn/news/202012/1536909.html", "release_time": "2020-12-23 09:52", "source": "汽车之家", "content": "", "web_source": "qicheshidai", "source_type": "0", "polarity": 1}
      136 '''
      137 def insertDataQuick(data_object):
      138     # db_init()
      139     sql = "INSERT INTO news_detail(title,url,release_time,source,content,web_source,source_type,polarity) VALUES(%s, %s, %s, %s, %s, %s, %s, %s)"
      140     # print(sql)
      141     try:
      142         cursor.execute(sql, (data_object["title"], data_object["url"], data_object["release_time"], data_object["source"], data_object["content"], data_object["web_source"],data_object["source_type"],data_object["polarity"]))
      143         # db.commit()
      144     except Exception as e:
      145         print("ERROR", e)
      146         db.rollback()
      147 def insert_Data_many(news_list):
      148     db_init()
      149     news_values = []
      150     for news in news_list:
      151         news_values.append((news["title"], news["url"], news["release_time"], news["web_source"], news["company"], news["source_type"]))
      152     cursor.executemany('INSERT INTO news_detail(title,url, release_time, web_source, company, source_type) VALUES(%s, %s, %s, %s, %s, %s)', news_values)
      153     db.commit()
      154     print("插入完成")
      155 
      156 def insertData(data_object):
      157     db_init()
      158     sql = "INSERT INTO news_detail(title,url,release_time,source,content,web_source,source_type,polarity) VALUES(%s, %s, %s, %s, %s, %s, %s, %s)"
      159     # print(sql)
      160     try:
      161         cursor.execute(sql, (data_object["title"], data_object["url"], data_object["release_time"], data_object["source"], data_object["content"], data_object["web_source"], data_object["source_type"],data_object["polarity"]))
      162         db.commit()
      163     except Exception as e:
      164         print("ERROR", e)
      165         db.rollback()
      166 
      167     # cursor.close()
      168     # db.commit()
      169     # 关闭数据库连接
      170     db.close()
      171 
      172 def updateData(latest_news_val, source_name_val):
      173     db_init()
      174     latest_news = json.dumps(latest_news_val, ensure_ascii=False)
      175     sql = "UPDATE source_info SET latest_news = '%s' WHERE source_name = '%s'" % (latest_news, source_name_val)
      176     try:
      177         cursor.execute(sql)
      178         db.commit()
      179     except Exception as e:
      180         print("ERROR", e)
      181         db.rollback()
      182 
      183 
      184 
      185 # latest_news_temp = ["新闻1","xxx"]
      186 # db_init()
      187 # data_ob = {
      188 #     "title": "x",
      189 #     "url": "http://sss",
      190 #     "release_time": "2020-11-11 10:30:00",
      191 #     "source": "sohu",
      192 #     "content": "c",
      193 #     "web_source": "sohu"
      194 # }
      195 # insertData(data_ob)
      196 # insertData(data_ob)
      197 # insertData(data_ob)
      198 # getData('sohu')
      199 # updateData(latest_news_temp, 'sohu')
      200 # setData()
      201 # get_latest_data("techweb")
      202 # get_unupdate_news()
      203 # get_unupdate_count()
      204 # check_news("寻电之路2:海外合资品牌的全面反攻", "qicheshidai")
      mysql_utils

     

    • 表结构设计 -demo

    • drop database blog;
      drop database IF EXISTS blog;
      create database blog default charset utf8 collate utf8_general_ci;
      use blog;
      
      create table user(
          id int not null auto_increment primary key,
          username varchar(16) not null,
          nickname varchar(16) not null,
          mobile char(11) not null,
          password varchar(64) not null,
          email varchar(64) not null,
          ctime datetime not null
      )default charset=utf8;
      
      
      create table article(
          id int not null auto_increment primary key,
          title varchar(255) not null,
          text text not null,
          read_count int default 0,
          comment_count int default 0,
          up_count int default 0,
          down_count int default 0,
          user_id int not null,
          ctime datetime not null,
          constraint fk_article_user foreign key (user_id) references user(id)
      )default charset=utf8;
      
      
      create table comment(
          id int not null auto_increment primary key,
          content varchar(255) not null,
          user_id int not null,
          article_id int not null,
          ctime datetime not null,
          constraint fk_comment_user foreign key (user_id) references user(id),
          constraint fk_comment_article foreign key (article_id) references article(id)
      )default charset=utf8;
      
      
      create table up_down(
          id int not null auto_increment primary key,
          choice tinyint not null,
          user_id int not null,
          article_id int not null,
          ctime datetime not null,
          constraint fk_up_down_user foreign key (user_id) references user(id),
          constraint fk_up_down_article foreign key (article_id) references article(id)
      )default charset=utf8;
      博客系统-表结构设计



    作者:华王 博客:https://www.cnblogs.com/huahuawang/
  • 相关阅读:
    mac 配置pycharm(2021.3版本) 和 clion(2019.3版本)
    深度学习神经网络backbone
    Windows获取CPU、内存和磁盘使用率脚本
    Unicode编码转换
    @ControllerAdvice全局数据预处理
    查看Linux系统内存、CPU、磁盘使用率和详细信息
    服务器nginx配置SSL证书后启动报错问题解决方案
    Inno Setup 寻找 AppId 的方法
    慢sql_查询条件加了函数导致索引失效
    k8s暂停一个pod
  • 原文地址:https://www.cnblogs.com/huahuawang/p/14725586.html
Copyright © 2020-2023  润新知