装置

装置mysql数据库的难度和oracle数据库几乎没得比,装置步骤如下:

装置MariaDB

yum install mariadb mariadb-server  # 装置,centos7默认的mysql就是mariadbsystemctl start mariadb  # 启动mariadbsystemctl enable mariadb  # 开机自启动mysql_secure_installation  # 设置root明码mysql -uroot -p  # 登录

装置pymysql

pip install pymysql

基本操作

数据库基本操作次要是:

  1. 创立连贯
  2. 获取游标
  3. 执行sql
  4. 提交事务:针对非查问性SQL

代码

import pymysql# connect函数关上数据库连贯conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')# cursor办法创立游标对象curcur = conn.cursor()# execute办法执行SQL语句cur.execute("SELECT VERSION()")# fetchone办法获取单条数据data = cur.fetchone()print ('Database version : {}'.format(data))# 敞开游标cur.close()# 敞开数据库连贯conn.close()

<!--more-->

DDL

DDL:数据定义语言。包含创立表,创立索引等等

import pymysql# connect函数关上数据库连贯conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')# cursor办法创立游标对象curcur = conn.cursor()# 创立表sql = '''create table user (         name char(20) not null,         age int,           sex char(1))'''cur.execute(sql)# 敞开游标cur.close()# 敞开数据库连贯conn.close()

DML

DML:数据操作语言,蕴含增删改三项操作。

insert

import pymysql# connect函数关上数据库连贯conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')# cursor办法创立游标对象curcur = conn.cursor()# 创立表sql = '''insert into user(name, age, sex) values('suncle', 18, 'm')'''try:    # 执行sql语句    cur.execute(sql)    # 提交到数据库执行    conn.commit()except:    # 如果产生谬误则回滚    conn.rollback()# 敞开游标cur.close()# 敞开数据库连贯conn.close()

update

import pymysql# connect函数关上数据库连贯conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')# cursor办法创立游标对象curcur = conn.cursor()# 创立表sql = '''update user t set t.age = 20 where t.name='suncle' '''try:    # 执行sql语句    cur.execute(sql)    # 提交到数据库执行    conn.commit()except:    # 如果产生谬误则回滚    conn.rollback()# 敞开游标cur.close()# 敞开数据库连贯conn.close()

delete

import pymysql# connect函数关上数据库连贯conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')# cursor办法创立游标对象curcur = conn.cursor()# 创立表sql = '''delete from user where age=20 '''try:    # 执行sql语句    cur.execute(sql)    # 提交到数据库执行    conn.commit()except:    # 如果产生谬误则回滚    conn.rollback()# 敞开游标cur.close()# 敞开数据库连贯conn.close()

QUERY

根底查问

次要有三个函数

  • cursor.fetchall 返回行的元组
  • cursor.fetchmany 返回行的元组, 能够指定返回前N行 相当于对fetchall切片fetchall[:N]
  • cursor.fetchone 返回首行, 相当于fetchall[0]

查问语句如下:

cur.execute('''select * from user t where t.age<=19;''')

三种办法失去的后果别离为:

cur.fetchall()  # (('suncle', 18, 'm'), ('suncle1', 19, 'm'))cur.fetchmany(1)  # (('suncle', 18, 'm'),)cur.fetchone()  # ('suncle', 18, 'm')

可见:每行数据也是一个元组, 元组的内容由sql决定

如果要让返回的数据带上列名,也就是要返回字典,那么就须要用到cursors.DictCursor。

DictCursor

创立cursor时创立DictCursor类型的就能够fetch回来字典模式的后果了

代码

import pymysqlconn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')# 创立cursor时指定cursor参数cursor=pymysql.cursors.DictCursor示意cursor类型cur = conn.cursor(cursor=pymysql.cursors.DictCursor)cur.execute('''select * from user t where t.age<=20;''')cur.fetchall()

fetchall返回后果为:

[{'age': 18, 'name': 'suncle', 'sex': 'm'}, {'age': 19, 'name': 'suncle1', 'sex': 'm'}, {'age': 20, 'name': 'suncle2', 'sex': 'm'}]

返回每一行记录都是一个字典,整体后果是由字典组成的列表。而默认的cursor是由元组组成的元组。

参数化查问

根底的SQL注入

import pymysqlconn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')cur = conn.cursor()def get_user(age=18):    sql = '''select * from user t where t.age<={};'''.format(age)    cur.execute(sql)    return cur.fetchall()get_user()  # 返回(('suncle', 18, 'm'),)get_user('18 or 1=1')  # 返回(('suncle', 18, 'm'), ('suncle1', 19, 'm'))

当传入参数的age中带sql条件的时候,就会产生sql注入,使得后果可能并不满足要求。

为了解决sql注入,咱们能够应用参数化查问。

应用参数化查问

以上代码做以下批改之后就能够防止sql注入

import pymysqlconn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')cur = conn.cursor()def get_user(age=18):    # 不论数据库定义的是什么类型,对立应用%s    sql = '''select * from user t where t.age<=%s;'''.format(age)    cur.execute(sql, (age, ))  # 参数化查问    return cur.fetchall()

参数化查问最大的劣势在于防止了SQL注入,同时参数化之后防止了sql屡次硬解析,能进步查问效率。所以,总是应该应用参数化查问。

上下文治理

数据库连贯和游标都反对上下文治理。

游标

查看cur实例对应Cursor类的办法

cur = conn.cursor()help(cur)

对应的with语句应用如下

with cur:    cur.execute('''select * from user''')cur.execute('''select * from user''')  # 抛出谬误:ProgrammingError: Cursor closed

with语句块完结之后cur就曾经敞开了。

连贯

通过help命令查看Connection类的__enter____exit__两种办法的实现

conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')help(conn)  # conn是Connection类

查看后果如下:

 |  __enter__(self) |      Context manager that returns a Cursor |   |  __exit__(self, exc, value, traceback) |      On successful exit, commit. On exception, rollback
  • __enter__办法会返回一个游标
  • __exit__办法:如果胜利推出就会主动提交commit,如果产生异样就会回滚rollback

对应的with语句应用如下

with conn as cur:    cur.execute('''update user t set t.age = 20 where t.name='suncle' ''')cur.execute('''select * from user''')  # 退出with块之后游标依然没有敞开

尽管游标没有敞开, 然而数据库操作曾经提交。

游标和连贯独特上下文治理

with conn as cur:    with cur:        cur.execute('''update user t set t.age = 20 where t.name='suncle' ''')

退出整个上下文治理块之后,游标会敞开,并且会主动提交。

数据库连接池

一般来说,应用程序拜访数据库的过程是:

  1. 装载数据库驱动程序
  2. 建设数据库连贯
  3. 拜访数据库,执行sql语句
  4. 断开数据库连贯

绝对于性能失常的SQL的执行效率来说,建设连贯是一个费时的流动,而且零碎还要为每一个连贯分配内存资源。在当初web申请的大并发量状况下,必然会导致频繁的数据库操作。而频繁的进行数据库连贯操作势必占用很多的系统资源,使得零碎的响应速度降落,重大的甚至会造成服务器的解体。

引入数据库连接池技术之后,应用程序拜访数据库的过程是:

  1. 申请数据库操作时,从连接池中取出创立好的数据库连贯
  2. 执行sql语句
  3. 一直开数据库连贯,而是放回连接池中,期待下次应用

连接池还有个长处就是能管制数据库的压力,当大量用户同时涌入时,连接池只会应用池限度数据库连贯数目,而不会不停的向数据库申请连贯,最初导致服务器解体。

Python实现数据库连接池

  • 应用队列Queue保留数据库连贯

代码如下

from queue import Queueimport pymysqlclass ConnectionPool():  # args和kwargs用来接管数据库url信息    def __init__(self, size, *args, **kwargs):        self.args = args        self.kwargs = kwargs        self.size = size        self.pool = Queue(maxsize=self.size)        for _ in range(self.size):            self.pool.put(self._connect())                def _connect(self):        return pymysql.connect(*self.args, **self.kwargs)        @staticmethod    def _close(conn):        conn.close()        def get_connection(self):        return self.pool.get()     def return_connection(self, conn):        return self.pool.put(conn)     def close_pool(self):        while not self.is_empty():            self._close(self.pool.get())     def is_empty(self):        return self.pool.empty()        def is_full(self):        return self.pool.full()        def current_connection_count(self):        return self.pool.qsize()        pool = ConnectionPool(20, host='192.168.110.13', user='root', password='123456', database='student')conn = pool.get_connection()  # 获取数据库连贯print(conn)  # <pymysql.connections.Connection at 0x7f6290300940>print(pool.current_connection_count())  # 19cur = conn.cursor()cur.execute("SELECT VERSION()")data = cur.fetchone()print ('Database version : {}'.format(data[0]))cur.close()pool.return_connection(conn)  # 敞开游标之后须要回收数据库连贯print(pool.current_connection_count())  # 20

记得帮我点赞哦!

精心整顿了计算机各个方向的从入门、进阶、实战的视频课程和电子书,依照目录正当分类,总能找到你须要的学习材料,还在等什么?快去关注下载吧!!!

朝思暮想,必有回响,小伙伴们帮我点个赞吧,非常感谢。

我是职场亮哥,YY高级软件工程师、四年工作教训,回绝咸鱼争当龙头的斜杠程序员。

听我说,提高多,程序人生一把梭

如果有幸能帮到你,请帮我点个【赞】,给个关注,如果能顺带评论给个激励,将不胜感激。

职场亮哥文章列表:更多文章

自己所有文章、答复都与版权保护平台有单干,著作权归职场亮哥所有,未经受权,转载必究!