第三篇 Python关于mysql的API--pymysql模块, mysql事务

python关于mysql的API--pymysql模块

pymysql是Python中操做MySQL的模块,其使用方法和py2的MySQLdb几乎相同。python

模块安装

pip install pymysql

在Pycharm里执行sql会遇到“SQL dialect is not configured”,解决办法:mysql

在File---->Setting--->Languages & Frameworks--->SQL Dialects中,选择对应的数据库,如MySQL,以后点击保存便可sql

 

执行sql语句

在Python里写原生sql,就是把原生sql放到了一个接口里去执行数据库

import pymysql

# 1. 链接数据库后返回可是一个链接对象,有这个链接对象,就能够对数据库进行操做
conn = pymysql.connect(
    host = "127.0.0.1",   # 数据库的ip地址
    port = "3306",        # 数据库的端口号
    user = "root",        # 登录数据库的用户名
    passwd = "123456",    # 登录数据库的密码
    db = "lesson54"       # 要链接的数据库,必须提早建立好,不然会链接出错
)

# 2.获取游标
# 有了游标,具体的sql语句就能够经过这个游标来执行了
cursor = conn.cursor()  # 返回的结果是一个元组的形式
cursor1 = conn.cursor(cursor1 = pymysql.cursors.DictCursor) # 返回的就是字典形式的光标

# 经过execute执行sql语句
# cursor.execute("具体的sql语句,增删改查")

# 3. 建立表
sql = "create table TEST(id int,name varchar (20))"  # 建立表的语句,复制给sql变量
cursor.execute(sql)   # 调用execute,建立表
cursor.execute()

# 4. 插入数据
ret =cursor.execute("insert into test values (1,'alex'),(2,'alvin')")
print(ret)  # 2, 返回的结果就是影响的行数

# 5. 查询
ret2 = cursor.execute("select * from test")
print(ret2)

# 6.拿到查询到的结果
print(cursor.fetchone())   # 从查询到的结果里取出一条,此时游标已经不在第一行了,而在下一行了
print(cursor.fetchall())   # 取出全部查询到的结果,因此此时取到的是剩下的全部数据
print(cursor.fetchmany(3))  # 指定取出3条查询结果

# 7. 调节游标的位置
# 上面6的步骤,游标的位置发生了变化
# 相对调节:根据当前游标的位置,进行向上或者向下调节几行
cursor.scroll(1,mode="relative") # 正数:向下, 负数:向上

# 绝对调节:无论当前游标在第几行,直接调整到第一行,调到几行数字就写几
cursor.scroll(1,mode="absolute")  



# .建立了链接对象,就要提交,提交以后再把链接关闭
conn.commit()
cursor.close()
conn.close()

若是放到了ORM里,就会彻底有一套本身的语法去代替sql语句安全

 

事务

事务命令

事务指逻辑上的一组操做,组成这组操做的各个单元,要不所有成功,要不所有不成功。服务器

数据库开启事务命令 session

start transaction 开启事务
Rollback 回滚事务,即撤销指定的sql语句(只能回退insert delete update语句),回滚到上一次commit的位置 Commit 提交事务,提交未存储的事务 savepoint 保留点 ,事务处理中设置的临时占位符 你能够对它发布回退(与整个事务回退不一样) 

 转帐实例:并发

UPDATE account set balance=balance-5000 WHERE name=”yuan”;
UPDATE account set balance=balance+5000 WHERE name=”xialv”;
-- 建立表
create table test2(id int PRIMARY KEY auto_increment,name VARCHAR(20)) engine=innodb;

-- 插入数据
INSERT INTO test2(name) VALUE ("alvin"),
                              ("yuan"),
                              ("xialv");



start transaction; -- 开启事务
insert into test2 (name)values('silv');
select * from test2;
commit;   -- 提交事务


-- 保留点

start transaction;
insert into test2 (name)values('wu');
savepoint insert_wu; -- 给上面刚才insert的命令起了个名字叫insert_wu,并设置一个保留点,对重要的sql,要紧挨着设置保留点
select * from test2;



delete from test2 where id=4;
savepoint delete1;
select * from test2;


delete from test2 where id=1;
savepoint delete2;
select * from test2;

rollback to delete1;  -- 回滚到某个设置的节点


select * from test2;

savepoint

python中调用数据库启动事务的方式less

import pymysql

#添加数据

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='yyy')

cursor = conn.cursor()


try:
    insertSQL0="INSERT INTO ACCOUNT2 (name,balance) VALUES ('oldboy',4000)"
    
    # 下面的是一组事务
    insertSQL1="UPDATE account2 set balance=balance-30 WHERE name='yuan'"
    insertSQL2="UPDATE account2 set balance=balance+30 WHERE name='xialv'"

    cursor = conn.cursor()

    cursor.execute(insertSQL0)
    conn.commit()

    cursor.execute(insertSQL1)
    raise Exception  # 模拟inserSQL2出现异常
    cursor.execute(insertSQL2)
    cursor.close()
    conn.commit()

except Exception as e:

    conn.rollback()  # 上面模拟insertSQL2出现异常了,就会执行回滚,回滚到上一次commit的地方
    conn.commit()


cursor.close()
conn.close()

事务特性

<1> 原子性(Atomicity):原子性是指事务是一个不可分割的工做单位,事务中的操做要么都发生,要么都不发生。数据库设计

<2> 一致性(Consistency):事务先后数据的完整性必须保持一致。在事务执行以前数据库是符合数据完整性约束的,不管事务是否执行成功,事务结束后的数据库中的数据也应该是符合完整性约束的。在某一时间点,若是数据库中的全部记录都能保证知足当前数据库中的全部约束,则能够说当前的数据库是符合数据完整性约束的。
好比删部门表前应该删掉关联员工(已经创建外键),若是数据库服务器发生错误,有一个员工没删掉,那么此时员工的部门表已经删除,那么就不符合完整性约束了,因此这样的数据库也就性能太差啦!

<3>隔离性(Isolation):事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

<4>持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即便数据库发生故障也不该该对其有任何影响。

3、隔离性:
将数据库设计为串行化程的数据库,让一张表在同一时间内只能有一个线程来操做。若是将数据库设计为这样,那数据库的效率过低了。因此数据库的设计这没有直接将数据库设计为串行化,而是为数据库提供多个隔离级别选项,使数据库的使用者能够根据使用状况本身定义到底须要什么样的隔离级别。

不考虑隔离性可能出现的问题:

脏读

--一个事务读取到了另外一个事务未提交的数据,这是特别危险的,要尽力防止。
        a 1000
        b 1000
        a:
            start transactionupdate set money=money+100 where name=b;
        b:
            start transaction;
            select * from account where name=b;--1100
            commit;
        a:
            rollback;
        b:  start transaction;
            select * from account where name=b;--1000

不可重复读

--在一个事务内读取表中的某一行数据,屡次读取结果不一样。(一个事务读取到了另外一个事务已经提交
-- 的数据--增长记录、删除记录、修改记录),在某写状况下并非问题,在另外一些状况下就是问题。

a:
start transaction;
select 活期帐户 from account where name=b;--1000    活期帐户:1000
select 按期帐户 from account where name=b;--1000   按期帐户:1000
select 固定资产 from account where name=b;--1000   固定资产:1000
------------------------------
b:
start transaction;
update set money=0 where name=b;
commit;
------------------------------
select 活期+按期+固定 from account where name=b; --2000 总资产: 2000

虚读

是指在一个事务内读取到了别的事务插入的数据,致使先后读取不一致。
(一个事务读取到了另外一个事务已经提交的数据---增长记录、删除记录),在某写状况下并非问题,在另外一些状况下就是问题。 b 1000 c 2000 d 3000 a: start transaction select sum(money) from account;---3000 3000 ------------------- d:start transaction; insert into account values(d,3000); commit; ------------------- select count(*)from account;---3 3 3000/3 = 1000 1000

四个隔离级别:
Serializable:可避免脏读、不可重复读、虚读状况的发生。(串行化)
Repeatable read:可避免脏读、不可重复读状况的发生。(可重复读)不能够避免虚读
Read committed:可避免脏读状况发生(读已提交)
Read uncommitted:最低级别,以上状况均没法保证。(读未提交)

安全性考虑:Serializable>Repeatable read>Read committed>Read uncommitted
数据库效率:Read uncommitted>Read committed>Repeatable read>Serializable

通常状况下,咱们会使用Repeatable read、Read committed mysql数据库默认的数据库隔离级别Repeatable read

mysql中设置数据库的隔离级别语句:

set [global/session] transaction isolation level xxxx;

若是使用global则修改的是数据库的默认隔离级别,全部新开的窗口的隔离级别继承自这个默认隔离级别若是使用session修改,则修改的是当前客户端的隔离级别,和数据库默认隔离级别无关。当前的客户端是什么隔离级别,就能防止什么隔离级别问题,和其余客户端是什么隔离级别无关。
mysql中设置数据库的隔离级别语句:

select @@tx_isolation;
相关文章
相关标签/搜索