Python与sql交互入门(mysql和sqlite)

(以下所有操作使用的均为Mac系统+pycharm为IDE,需要有数据库理论基础和sql语法知识)

目录

1.终端sql操作(mysql数据库)

--连接数据库

--退出数据库

--查看所有数据库

--显示时间

--显示数据库版本

--创建数据库

--查看创建数据库语句

--删除数据库

--查看当前使用的数据库

--使用数据库

--(选择需要修改的数据库后)创建表

--查看所有表

--查看表结构

--查看系统创建表语句(格式化你新建表的语句)

--修改表结构

--插入数据

--查询后的结果一列中显示多种信息

--分页

--读取数据

--子母表同时更新数据

--创建用户并授予权限

--备份

--恢复

2.mysql和python交互

安装模块

引入模块

Connection对象

Cursor对象

mysql命令参数

3.python与sqlite交互

 引入模块

连接数据库

操作数据库

4. sql注入

5. sql索引


1.终端sql操作(mysql数据库)

--连接数据库

mysql -uroot -p (后输入mysql密码即可)

--退出数据库

exit/quit/ctrl+d

(sql语句不区分大小写,每句后面都必须有;)

--查看所有数据库

mysql>show databases;

--显示时间

select now();

--显示数据库版本

select version();

--创建数据库

create database python-04;

--查看创建数据库语句

show create database python04;

--删除数据库

drop database python-04;(会报错,因为系统默认将-04识别为新的一部分数据,而我们需要python-04作为整体)

改为:drop database `python-04`;

--查看当前使用的数据库

select database();

--使用数据库

use python-04;

--(选择需要修改的数据库后)创建表

create table lilho(id int unsigned primary key not null auto_increment, name varchar(20));(可换行)

create table lilho(

        id int primary key not null auto_increment,

        name varchar(20)

        gender enum("male","female","secret") default "secret"

);

--查看所有表

show tables;

--查看表结构

desc lilho;

--查看系统创建表语句(格式化你新建表的语句)

show create table lilho;

--修改表结构

①重命名:alter table 表名 change 原名 新名 类型及约束;

②不重命名:alter table 表名 modify 列名 类型及约束;

③增加列:alter table 表名 add 列名 类型及约束;

④删除列:alter table 表名 drop 列名;

⑤增删外键:alter table 表名 add foreign key (外键名) references 引用表名(引用列名);

                       alter table 表名 drop foreign key 外键名;

--插入数据

insert into lilho values(0,"sdhg");  整体插入,一一对应

insert into lilho (name) values("shjgd");  部分插入,先写列名,再输入数值;并且可以同时添加多个

如果是从另一个表中选择数据插入到新表中,不需要values关键字:

insert into lilho (name, age) select cname,cage from anther_table;

--查询后的结果一列中显示多种信息

select group_concat(name,"_",id) from lilho;

--分页

limit start,num;(从start+1开始显示,num为显示的个数,无论查询的个数是多少,只显示不超过num个,start可以省略,默认从0开始搜索)

 用limit语句实现分页:limit (第N页-1)*每页的个数, 每页的个数;

顺序:where,order by, limit(不可以将order by 放在limit后面)

--读取数据

将.sql文件读进数据库中,使用source + 文件名.sql

--子母表同时更新数据

(假设goods_cates是母表,包含三列;goods是子表,两列都是从goods_cates取出来的列,通过内连接和update语句进行同步跟新)

update goods as g inner join goods_cate as c on g.ganame = c.cname set g.cate_name = c.id;

--创建用户并授予权限

grant 权限列表 on 数据库 to '用户名'@'访问主机' identied by '密码';

--备份

mysqldump -uroot -p 数据库名 > 文件名.sql (“>”表示重定向输出)

--恢复

mysql -uroot -p 新建数据库名 < 文件名.sql  

(其他sql语句自行学习数据库相关知识)


2.mysql和python交互

  • 安装模块

sudo pip3 install pymysql
  • 引入模块

from pymysql import *
  • Connection对象

        用于建立与数据库的连接。

conn = connect(参数列表)

参数host:连接的mysql主机,如果是本机为'localhost'
参数port:连接的mysql主机的端口,默认为3306
参数database:database的名称
参数user:连接的用户名
参数password:连接的密码
参数的charset:通信采用的编码方式,推荐使用utf8(python3.8中不需要传递该参数)

对象方法:
.close() 关闭连接
.commit() 提交
.rollback() 返回,在提交前可以返回到上一次提交时的数据库内容,当前的sql操作不起作用。
.cursor() 返回Cursor对象,用于执行sql语句并返回结果
  • Cursor对象

        用于执行sql语句,通过connect对象的.cursor()方法获取一个实例。

sc1 = conn.cursor()

对象方法:
.close() 关闭
.execute("执行语句") 返回受影响的行数
.fetchone() 执行查询时,获取查询结果集的第一个行数据,返回一个元组,当多次调用时依次往下获取结果
.fetchall() 执行查询时,获取结果集的所有行。一行构成一个元组,再将这些元组装入一个元组返回

对象属性:
.rowcount 只读属性,表示最近一次执行语句后影响的行数
.connection 获取当前的连接对象

简单举例:

目前操作的数据库如下:

from pymysql import *

conn = connect(host='localhost', port=3306, user='root', password ='880117', database='hsj')
cs = conn.cursor()

mysql_insert = 'insert into lilho values(0,"hsdj",12,"female");'
cs.execute(mysql_insert)
sql = "ALTER TABLE lilho AUTO_INCREMENT = 1;"
cs.execute(sql)
count = cs.execute("select * from lilho;")

for i in range(count):
    print(cs.fetchone())

# 如果有增删改操作需要将修改提交给数据库
conn.commit()
cs.close()
conn.close()

运行结果:
(1, 'hsj', 23, 'male')
(2, 'shd', None, 'secret')
(3, 'hsdj', 12, 'female')
  • mysql命令参数

             如果数据复杂,组合的sql语句可能无效(如字段汇总含有双引号),因此可以带参数的execute命令:

cursor.execute(带参数的SQL命令,(参数列表))

            其中带参数的sql命令是sql把不缺的参数值用参数%s表示,参数列表是对应的参数的值,放在一个元组或列表中。


3.python与sqlite交互

       sqlite是一种轻型数据库,它的设计目标是嵌入式的,并且python3自带对sqlite的支持。引入模块后,除了在sqlite中,数据库参数不是%s改为了?,其他操作与mysql基本相同(sqlite的数据类型简单一点)。

  •  引入模块

import sqlite3
  • 连接数据库

con = sqlite3.connect("test.db")  # test.db是sqlite3数据文件
  • 操作数据库

cs = con.cursor()
cs.execute(SQL)
con.submit()
cs.close()
con.close()

         举例说明:建立一个学生数据库students.db,并创建一张学生记录表students,包含学号Sno,姓名Sname,性别Sgender,年龄Sage字段。

import sqlite3

sql = """
create table students
(
   Sno int unsigned primary key not null,
   Sname varchar(16),
   Sgender varchar(6) default "secret",
   Sage int unsigned
)
"""

con = sqlite3.connect("students.db")
cs = con.cursor()

cs.execute(sql)
cs.execute('insert into students values(1, "小明", "male", 13),(2,"小红","female",15),(3, "小凯", "secret", 14)')

cs.execute("select * from students")
rows = cs.fetchall()
for row in rows:
    print(row[0], row[1], row[2])
con.commit()

cs.close()
con.close()

运行结果:
1 小明 male
2 小红 female
3 小凯 secret

4. sql注入

       sql注入可以理解为与用户交互时,用户恶意输入恒为true的代码来窃取信息(如'or 1=1')。

       简单的解决方案:将用户输入的信息传进列表中,让execute函数自动拼装,而不是采用python字符串填充的方法。

# 会导致sql注入
sql = 'select * from lilhoe where name = "{}";'.format(input());
cursor.execute(sql)
# 不会导致sql注入
input_list = [input()]
sql = 'select * from lilhoe where name = {};'
cursor.execute(sql, input_list)

5. sql索引

       索引是一种特殊的文件,InnoDB数据表上的索引是表空间的一个组成部分(linux采用的是InnoDb数据表),它们包含着对数据表里所有记录的引用指针)。

下面通过一个demo来体会一下建立索引之后查找的快速:

  • 首先从终端创建一个测试表:test_index
create table test_index(title varchar(20));
  • 通过python插入100000条数据:
from pymysql import *   

conn = connect(host='localhost', port=3306, user='root', password ='880117', database='hsj')  
cs = conn.cursor()           
for i in range(10000): 
    cs.execute("insert into test_index values('ha{}')".format(i))                                                                  

conn.commit()                                                      
cs.close()
conn.close()
  • 在终端开启所有工作的时间统计功能:
set profiling = 1;
  • 查询第100000条数据:
select * from test_index where title = "ha99999";
  • 查看执行时间:
show profiles;
  • 可以查看当刚刚查询语句执行的时间:
  • 为表test_index的title字段建立一个索引:
--title是字符串类型,所以需要加入长度
create index title_index on test_index(title(20));
  • 再一次执行查询第100000条语句,并查看执时间:

     比较两次的时间可以得出结论:在需要查找的字段建立索引后,查找速度明显提高。

注意:

          建立太多的索引会影响插入和更新的速度,因为它同样需要更新每个索引文件,且建立索引会占用磁盘空间。

猜你喜欢

转载自blog.csdn.net/m0_45338067/article/details/107999192