python 里面操作mysql时连接可能报错:
ex: cannot connnect...
- host 写错
- port 写错
- 服务器没启动
ex: unknown database ...
- db / database
ex: Access denied ...
- user
- passwd / password
- 账号不允许远程连接
补充:
事务的特点是什么?
- ACID特性 (面试注意)
- 原子性(Atomicity):不可分割要么成功要么失败
- 一致性(consistency):事务前后数据状态要保持一致
- 隔离性(Isolation):多个事务不能看到对方的中间状态(提交或者回滚之前的状态)
- 持久性(Duration):事务完成后数据要持久化(事务的影响要反映在物理存储上)
插入数据
import pymysql
def main():
#connection(连接) / cursor(游标)
#用的是iso--8859-1编码 所有不能传中文 如果有中文就要改成utf8/utf8mb4(用于有特殊字符比如emoji四个字节字符)
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='hr',charset='utf8',autocommit=False)
#如果连上数据库这里conn就会返回个连接对象 localhost是连本地 可以写ip连别人 port是默认
#mysql连接数是有限制的 没有设置默认是150个连接 所有用完了就一定要释放资源
try:
#发数据 创建cursor对象
with conn.cursor() as cursor: #创建游标 用完了也要关,不然后面用不了 ,所以用了with 上下文语法里面 ,用完了自己关
#向数据库发出SQL语句
#excute返回行数就代表插入成功
dno = input('部门编号:')
dname = input('部门名称:')
dloc = input('部门所在地:')
result = cursor.execute('insert into tbdept values (%s,%s,%s)',(dno,dname,dloc))
#这里必须用占位符的形式传入参数,否则传入参数不正确
#这里要注意:不管给的什么数据类型,占位符都必须写%s 这里不用%d %f什么的
#写带占位符的sql是没有被sql注射攻击风险的推荐使用 ,会自动补全“”
#下面这个是命名占位符的写法
# result = cursor.execute('insert into tbdept values (%(no)s,%(name)s,%(loc)s)', {'no':dno,'name': dname,'loc': dloc})
print(result)
conn.commit() #写了这句话 才能提交 执行的操作才会在mysql里真正执行 因为上面默认是False
finally:
conn.close()
if __name__ == '__main__':
main()
比如新增部门70,督察部,成都
部门编号:70
部门名称:督察部
部门所在地:成都
1
删除数据
import pymysql
def main():
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='hr',charset='utf8',autocommit=False)
try:
with conn.cursor() as cursor:
dno = input('部门编号:')
result = cursor.execute('delete from tbdept where dno=%s',(dno,) )
#(dno,) 这里是个元组 所以必须加逗号 这里写元祖字典最保险建议用法 %s s是安全的意思save
#千万不要写下面这种 zaimysql里面这样存在被人攻击修改数据的风险 --这是SQL注射攻击的风险
# fno ='delete from tbdept where dno=%d'% dno
# result = cursor.execute(fno)
#如果事务中的所有操作全部都成功了最后手动提交事务
#所以建议手动提交,这样可以在失败时做到回滚
conn.commit()
print('删除成功'if result == 1 else '删除失败')
except:
#如果事务中的操作有任何一个发生了异常状况就回滚事务
conn.rollback()
#就是发生错误了 可以回滚
finally:
conn.close()
if __name__ == '__main__':
main()
查询
import pymysql
def main():
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='hr',charset='utf8',autocommit=False)
try:
with conn.cursor() as cursor:
cursor.execute('select dno ,dname,dloc from tbdept limit 3')
#这里实际开发不允许写select * limit 3 是给限制查询3条
result = cursor.fetchone()
while result:
print(result)
# print(result[1],result[2])
result = cursor.fetchone()
#fetcheone()是一条一条显示出
#result是个集合 reselut[1]就拿到部门名 print(result[1])
finally:
conn.close()
if __name__ == '__main__':
main()
import pymysql
from hrs import Dept
#这里是导入了上面的模块
def main():
# config = {
# 'host':'localhost',
# 'user':'root',
# 'passwd':'123456',
# 'db':'hr',
# 'charset':'utf8',
# 'cursorclass':pymysql.cursors.DictCursor
#
# }
# conn = pymysql.connect(**config)
# # conn也可以通过上面字典的形式传入
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='hr',charset='utf8',autocommit=False,cursorclass=pymysql.cursors.DictCursor)
#cursorclass=pymysql.cursors.DictCursor 这个设置游标类型 待会儿下面是拿的时候就是拿字典
try:
with conn.cursor() as cursor:
cursor.execute('select dno ,dname,dloc from tbdept limit 3')
#这里实际开发不允许写select * limit 3 是给限制查询3条
result = cursor.fetchone()
while result:
#关系型数据库 -关系模型
#Python 程序- 对象模型
#ORM - Object Relation Mapping 对象和关系的映射
# Alchemy 是完成对象和关系模型的双向转换的
# 有了ORM以后操作数据库就再也不用写SQL原生的了 但是性能会下降
dept =Dept(**result)
#Dept是引用另外文件的对象 **把字典拆成键值对
print(dept.name,dept.no,dept.location)
result = cursor.fetchone()
finally:
conn.close()
if __name__ == '__main__':
main()
上诉所用mysql数据:https://git.coding.net/Asenli/pythonmysql.git
可以用Navicat MySQL 打开附件