python 全栈开发,Day63(子查询,MySQl创建用户和授权,可视化工具Navicat的使用,pymysql模块的使用)...
昨日內容回顧
外鍵的變種三種關系:多對一:左表的多 對右表一 成立左邊的一 對右表多 不成立foreign key(從表的id) refreences 主表的(id)多對多建立第三張表(foreign key)一對一foreign key+unique單表查詢: (1)wheregroup by: 分組,通過某個字段 select age,count(1) from user group by age having avg(age)>25;havingorder bylimit 1,2多表查詢:內連接:select * from t1 inner join t2 ; 笛卡爾積select * from t1 inner join t2 on t2.tid = t1.id;左連接:select * from t1 left join t2 on t2.tid = t1.id;右連接全連接#select name from department where id in(select dep_id from employee where age > 25);select * from employee inner join departmenton employee.dep_id = department.id where age > 25;子查詢 #查詢平均年齡在25歲以上的部門名 select * from departmentwhere id in(select dep_id from employee group by dep_id having avg(age) > 25);查詢每個部門最新入職的那位員工 select employee.id,employee.name from employee inner join (select post,max(hire_date) as new_date from employee group by post) as A on employee.post=A.post where employee.hire_date = A.new_date; View Code取第一名,limit 0,1
取第二名,limit 1,1
取第三名,limit 2,1
?
一、子查詢
1:子查詢是將一個查詢語句嵌套在另一個查詢語句中。 2:內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。 3:子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字 4:還可以包含比較運算符:= 、 !=、> 、<等例子:
(1)帶in關鍵字的子查詢
1. 查詢平均年齡在25歲以上的部門名
步驟分解:
先找出平均年齡大于25歲的的員工部門id
mysql> select dep_id from employee group by dep_id having avg(age) > 25; +--------+ | dep_id | +--------+ | 201 | | 202 | +--------+ 2 rows in set (0.00 sec) View Code根據部門id,到部門表department中查詢。就可以找到部門名,需要用到上面的查詢結果。
使用where id in (...) 可以得到多條結果。
select id,name from departmentwhere id in (select dep_id from employee group by dep_id having avg(age) > 25);#返回結果: +------+--------------+ | id | name | +------+--------------+ | 201 | 人力資源 | | 202 | 銷售 | +------+--------------+ View Code2. 查看技術部員工姓名
步驟分解:
先到部門表中查詢技術部的id
mysql> select id from department where name='技術'; +------+ | id | +------+ | 200 | +------+ 1 row in set (0.00 sec) View Code根據技術部id,到員工表查詢對應的員工姓名
select name from employeewhere dep_id in (select id from department where name='技術');#返回結果: +--------+ | name | +--------+ | egon | | nvshen | +--------+ View Code3. 查看不足1人的部門名
步驟分解:
先從員工表中查詢所有的部門id
mysql> select dep_id from employee group by dep_id; +--------+ | dep_id | +--------+ | 200 | | 201 | | 202 | | 204 | +--------+ 4 rows in set (0.00 sec) View Code使用where id not in (...) 查詢不包含上面的id,就可以得到沒有員工的部門
select name from departmentwhere id not in (select dep_id from employee group by dep_id);#返回結果: +--------+ | name | +--------+ | 運營 | +--------+ View Code(2)帶比較運算符的子查詢
#比較運算符:=、!=、>、>=、<、<=、<> #查詢大于所有人平均年齡的員工名與年齡 mysql> select name,age from employee where age > (select avg(age) from employee); +---------+------+ | name | age | +---------+------+ | alex | 48 | | wupeiqi | 38 | +---------+------+#查詢大于部門內平均年齡的員工名、年齡 思路:(1)先對員工表(employee)中的人員分組(group by),查詢出dep_id以及平均年齡。(2)將查出的結果作為臨時表,再對根據臨時表的dep_id和employee的dep_id作為篩選條件將employee表和臨時表進行內連接。(3)最后再將employee員工的年齡是大于平均年齡的員工名字和年齡篩選。mysql> select t1.name,t1.age from employee as t1inner join(select dep_id,avg(age) as avg_age from employee group by dep_id) as t2on t1.dep_id = t2.dep_idwhere t1.age > t2.avg_age;#返回結果 +------+------+ | name | age | +------+------+ | alex | 48 | +------+------+ View Code(3)帶EXISTS關鍵字的子查詢
#EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。而是返回一個真假值。True或False #當返回True時,外層查詢語句將進行查詢;當返回值為False時,外層查詢語句不進行查詢 #department表中存在dept_id=203,Ture mysql> select * from employee where exists (select id from department where id=200); +----+----------+--------+------+--------+ | id | name | sex | age | dep_id | +----+----------+--------+------+--------+ | 1 | egon | male | 18 | 200 | | 2 | alex | female | 48 | 201 | | 3 | wupeiqi | male | 38 | 201 | | 4 | yuanhao | female | 28 | 202 | | 5 | nvshen | male | 18 | 200 | | 6 | xiaomage | female | 18 | 204 | +----+----------+--------+------+--------+ #department表中存在dept_id=205,False mysql> select * from employee where exists (select id from department where id=204); Empty set (0.00 sec) View Code小練習:
查詢每個部門最新入職的那位員工
#刪除已存在的表 mysql> drop table employee; Query OK, 0 rows affected (0.19 sec)#創建表 create table employee( id int not null unique auto_increment, name varchar(20) not null, sex enum('male','female') not null default 'male', #大部分是男的 age int(3) unsigned not null default 28, hire_date date not null, post varchar(50), post_comment varchar(100), salary double(15,2), office int, #一個部門一個房間 depart_id int );#查看表結構 mysql> desc employee; +--------------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | NO | | NULL | | | sex | enum('male','female') | NO | | male | | | age | int(3) unsigned | NO | | 28 | | | hire_date | date | NO | | NULL | | | post | varchar(50) | YES | | NULL | | | post_comment | varchar(100) | YES | | NULL | | | salary | double(15,2) | YES | | NULL | | | office | int(11) | YES | | NULL | | | depart_id | int(11) | YES | | NULL | | +--------------+-----------------------+------+-----+---------+----------------+#插入記錄 #三個部門:教學,銷售,運營 insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values ('egon','male',18,'20170301','老男孩駐沙河辦事處外交大使',7300.33,401,1), #以下是教學部 ('alex','male',78,'20150302','teacher',1000000.31,401,1), ('wupeiqi','male',81,'20130305','teacher',8300,401,1), ('yuanhao','male',73,'20140701','teacher',3500,401,1), ('liwenzhou','male',28,'20121101','teacher',2100,401,1), ('jingliyang','female',18,'20110211','teacher',9000,401,1), ('jinxin','male',18,'19000301','teacher',30000,401,1), ('成龍','male',48,'20101111','teacher',10000,401,1),('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是銷售部門 ('丫丫','female',38,'20101101','sale',2000.35,402,2), ('丁丁','female',18,'20110312','sale',1000.37,402,2), ('星星','female',18,'20160513','sale',3000.29,402,2), ('格格','female',28,'20170127','sale',4000.33,402,2),('張野','male',28,'20160311','operation',10000.13,403,3), #以下是運營部門 ('程咬金','male',18,'19970312','operation',20000,403,3), ('程咬銀','female',18,'20130311','operation',19000,403,3), ('程咬銅','male',18,'20150411','operation',18000,403,3), ('程咬鐵','female',18,'20140512','operation',17000,403,3) ; View Code小練習題答案
#最新入職,使用max(hire_date) 就可以獲取。 #先查詢每個部門最新入職的部門名和日期 mysql> select post,max(hire_date) as new_date from employee group by post; +-----------------------------------------+------------+ | post | new_date | +-----------------------------------------+------------+ | operation | 2016-03-11 | | sale | 2017-01-27 | | teacher | 2015-03-02 | | 老男孩駐沙河辦事處外交大使 | 2017-03-01 | +-----------------------------------------+------------+ 4 rows in set (0.00 sec) #根據上一個結果,使用子查詢得到員工姓名 select t1.post,t1.name,t1.hire_date from employee as t1 inner join (select post,max(hire_date) as new_date from employee group by post) as t2 on t1.post=t2.post;#返回結果 +-----------------------------------------+------------+------------+ | post | name | hire_date | +-----------------------------------------+------------+------------+ | 老男孩駐沙河辦事處外交大使 | egon | 2017-03-01 | | teacher | alex | 2015-03-02 | | teacher | wupeiqi | 2013-03-05 | | teacher | yuanhao | 2014-07-01 | | teacher | liwenzhou | 2012-11-01 | | teacher | jingliyang | 2011-02-11 | | teacher | jinxin | 1900-03-01 | | teacher | 成龍 | 2010-11-11 | | sale | 歪歪 | 2015-03-11 | | sale | 丫丫 | 2010-11-01 | | sale | 丁丁 | 2011-03-12 | | sale | 星星 | 2016-05-13 | | sale | 格格 | 2017-01-27 | | operation | 張野 | 2016-03-11 | | operation | 程咬金 | 1997-03-12 | | operation | 程咬銀 | 2013-03-11 | | operation | 程咬銅 | 2015-04-11 | | operation | 程咬鐵 | 2014-05-12 | +-----------------------------------------+------------+------------+#最后取出2個臨時表中,最新入職日期相等的結果 select t1.post,t1.name,t1.hire_date from employee as t1 inner join (select post,max(hire_date) as new_date from employee group by post) as t2 on t1.post=t2.post where t1.hire_date=t2.new_date;#返回結果 +-----------------------------------------+--------+------------+ | post | name | hire_date | +-----------------------------------------+--------+------------+ | 老男孩駐沙河辦事處外交大使 | egon | 2017-03-01 | | teacher | alex | 2015-03-02 | | sale | 格格 | 2017-01-27 | | operation | 張野 | 2016-03-11 | +-----------------------------------------+--------+------------+ 4 rows in set (0.00 sec) View Code?
一、MySQl創建用戶和授權
權限管理
我們知道我們的最高權限管理者是root用戶,它擁有著最高的權限操作。包括select、update、delete、update、grant等操作。那么一般情況在公司之后DBA工程師會創建一個用戶和密碼,讓你去連接數據庫的操作,并給當前的用戶設置某個操作的權限(或者所有權限)。那么這時就需要我們來簡單了解一下:
- 如何創建用戶和密碼
- 給當前的用戶授權
- 移除當前用戶的權限
如果你想創建一個新的用戶,則需要以下操作:
1.必須使用root進入到mysql數據庫下
mysql -u rootmysql> use mysql Database changed?
2.對新用戶增刪改
(1). 創建用戶
1.創建用戶: # 指定ip:192.118.1.1的mjj用戶登錄 create user 'mjj'@'192.118.1.1' identified by '123'; # 指定ip:192.118.1.開頭的mjj用戶登錄 create user 'mjj'@'192.118.1.%' identified by '123'; # 指定任何ip的mjj用戶登錄 create user 'mjj'@'%' identified by '123'; View Code(2).?刪除用戶
#語法: drop user '用戶名'@'IP地址';#舉例:刪除192.118.1.1的mjj用戶登錄 mysql> drop user 'mjj'@'192.118.1.1'; Query OK, 0 rows affected (0.00 sec) View Code注意:刪除用戶不能直接對mysql.user表直接進行操作。
delete from mysql.user where User='mjj';必須使用drop user刪除才行。
(3).?修改用戶
#格式: rename user '用戶名'@'IP地址' to '新用戶名'@'IP地址';#舉例:修改192.118.1.開頭的mjj用戶的信息 mysql> rename user 'mjj'@'192.118.1.%' to 'msc'@'192.168.10.%'; Query OK, 0 rows affected (0.00 sec) View Code(4). 修改密碼
#格式: SET PASSWORD FOR '用戶名'@'IP地址' = PASSWORD('新密碼');#舉例:修改msc的密碼 mysql> SET PASSWORD FOR 'msc'@'192.168.10.%' = PASSWORD('123'); Query OK, 0 rows affected, 1 warning (0.00 sec) View Code3.對當前的用戶授權管理
(1). 查看權限
#語法: show grants for '用戶'@'IP地址'#舉例:查詢msc用戶 mysql> show grants for 'msc'@'192.168.10.%'; +--------------------------------------------+ | Grants for msc@192.168.10.% | +--------------------------------------------+ | GRANT USAGE ON *.* TO 'msc'@'192.168.10.%' | +--------------------------------------------+ 1 row in set (0.00 sec) View Code(2). 授權
#語法: 1.授權指定權限 grant 權限1,權限2,權限3 on 數據庫名.表名 to "用戶"@'IP地址';#舉例:給msc用戶授權查詢,插入,更新 權限。 mysql> grant select ,insert,update on db1.employee to "msc"@'192.168.10.%'; Query OK, 0 rows affected (0.00 sec)2.授權所有權限 grant all privileges on 數據庫名.表名 to "用戶"@'IP地址';#舉例:給msc用戶所有權限 mysql> grant all privileges on db1.employee to "msc"@'192.168.10.%'; Query OK, 0 rows affected (0.00 sec) View Code注意:不能對同一個用戶,多次授權不同的權限。否則會有多條授權規則,最終以最嚴格的權限為準。
(3). 取消權限
#語法: #取消指定權限 revoke 權限1 on 數據庫名.表名 from "用戶"@'IP地址';#舉例:取消msc用戶的查詢權限 mysql> revoke select on db1.employee from "msc"@'192.168.10.%'; Query OK, 0 rows affected (0.00 sec)#取消所有權限 revoke all privileges on 數據庫名.表名 from "用戶"@'IP地址';#舉例:取消msc用戶employee表所有權限 mysql> revoke all privileges on db1.employee from "msc"@'192.168.10.%'; Query OK, 0 rows affected (0.00 sec)#舉例:取消msc用戶所有數據庫所有表的權限 mysql> revoke all privileges on *.* from "msc"@'192.168.10.%'; Query OK, 0 rows affected (0.00 sec) View Codeps:在公司中,一般情況下是DBA工程師來做這些授權工作。給你一個用戶名和密碼,你來連接就可以了。
4.MySql備份命令行操作
備份1:數據表結構+數據
#注意:在是mysql>外面執行 C:\Users\xiao>mysqldump -u root -p db1 > db1.sql Enter password:#從上面可以看出,當前執行命令的路徑為C:\Users\xiao,進入此目錄,就可以看到db1.sql文件了。 View Code備份2:數據表結構
C:\Users\xiao>mysqldump -u root -p -d db1 > db2.sql Enter password:#進入C:\Users\xiao目錄,就可以看到文件db2.sql View Code恢復:導入現有的數據到某個數據庫
#進入數據庫 C:\Users\xiao>mysql -u root -p Enter password:#1.先創建一個新的數據庫 mysql> create database db10; #退出 mysql> exit; Bye#2.將已有的數據庫文件導入到db10數據庫中 C:\Users\xiao>mysqldump -u root -p -d db10 < db1.sql Enter password: -- MySQL dump 10.13 Distrib 5.7.22, for Win64 (x86_64) ... -- Dump completed on 2018-06-14 17:46:50出現completed 就表示導入完成 View Code
二、掌握Navicat的基本使用
本節重點:
-
掌握Navicat的基本使用
官網下載:https://www.navicat.com/en/products/navicat-for-mysql
百度網盤下載:
鏈接:https://pan.baidu.com/s/1vQI__mrJhTjGz0fAdY_pUA 密碼:frjg
官網的要錢,百度網盤是破解版的,只支持64位
32位系統,請訪問鏈接:https://pan.baidu.com/s/1bpo5mqj
?
下面主要演示64位版本的。
1.安裝軟件
解壓navicat11.1.12_premium_cs_x64.rar文件。先執行navicat111_premium_cs_x64.exe文件
?后面的步驟,直接下一步,下一步,就可以了。
選擇桌面圖標,右鍵屬性-->快捷方式-->打開文件位置,就能打開安裝路徑。
默認的安裝路徑為C:\Program Files\PremiumSoft\Navicat Premium
將壓縮包里面的navicat.exe復制到此路徑,選擇覆蓋!這樣就完成了破解。注意不要更新!!!
2.連接MySQL
雙擊桌面圖標,點擊連接-->MySQL
?
選項說明:
連接名:名字可以隨便寫
主機或IP地址:如果mysql在本機上,直接寫localhost即可。如果是遠程的,請填寫IP地址。
端口:mysql默認端口為3306,如果服務器有更改過,請填寫對應的端口號。
用戶名:授權的用戶
密碼:認證密碼,由于密碼為空,這里就不用填寫了。
點擊下面的連接測試,測試ok之后,點擊確定
雙擊localhost,就可以看到此用戶能訪問的數據庫
3.新建數據庫
右鍵-->新建數據庫
輸入數據庫名,字符集選擇utf-8
?這樣數據庫就創建好了
4.新建表
雙擊db2,選擇新建表
?
?輸入字段名id-->選擇數據類型int-->選擇主鍵-->勾選自動遞增-->勾選無符號
新增第二個字典name
點擊添加欄位-->輸入字段名name-->選擇varchar-->長度為20
最后點擊上面的保存按鈕,輸入表名t1
5.插入數據
雙擊t1表,就打開表了
添加數據張三
點擊下面的 √,一條數據就插入好了
點擊左邊的 + ,可以繼續添加數據
添加3條數據
6. 新建查詢
點擊上方的查詢
點擊下面的新建查詢
輸入sql語句,點擊運行,結果就出來了!
注意:
批量加注釋:ctrl+?鍵
批量去注釋:ctrl+shift+?鍵
?
7. 備份庫/表
備份庫
選中數據庫db2-->右鍵轉儲SQL文件-->結構和數據
?先選擇保存位置,這里選擇的是桌面,點擊保存
?
提示已經完成了,點擊關閉按鈕。千萬不要點擊開始,否則它會重新導出一次!
桌面就有一個db2.sql文件
備份表
選擇要備份的表-->右鍵轉儲SQL文件-->結構和數據
?
保存位置為桌面,點擊保存
點擊關閉按鈕,桌面會有一個t1.sql文件
?
需要掌握基本的操作,就是上面列舉上面那些。
?
三、pymysql模塊的使用
本節重點:
-
pymysql的下載和使用
-
execute()之sql注入
-
增、刪、改:conn.commit()
-
查:fetchone、fetchmany、fetchall
?
一、pymysql的下載和使用
之前我們都是通過MySQL自帶的命令行客戶端工具mysql來操作數據庫,那如何在python程序中操作數據庫呢?這就用到了pymysql模塊,該模塊本質就是一個套接字客戶端軟件,使用前需要事先安裝。
(1)pymysql模塊的下載
pip3 install pymysql(2)pymysql的使用
準備基礎數據
#創建數據庫db2,如果已存在,請忽略 CREATE DATABASE db2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;#創建用戶表 CREATE TABLE `userinfo` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',`username` varchar(20) NOT NULL COMMENT '用戶名',`password` varchar(32) NOT NULL COMMENT '密碼',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶表';#插入一條數據 INSERT INTO `db2`.`userinfo` (`id`, `username`, `password`) VALUES ('1', 'qiwei', '123'); View Code實現:使用Python實現用戶登錄,如果用戶存在則登錄成功(假設該用戶已在數據庫中)
#導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()# 注意%s需要加引號 sql = "select * from userinfo where username='%s' and password='%s'" % (user, pwd) print('sql語句:',sql)# 3.執行sql語句 cursor.execute(sql)result = cursor.execute(sql) # 執行sql語句,返回sql查詢成功的記錄數目 print('返回記錄數:',result)# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()if result:print('登陸成功') else:print('登錄失敗') View Code使用pycharm執行py文件,效果如下:
先來一個錯誤的
再來一個正確的
查看connect源代碼
def __init__(self, host=None, user=None, password="",database=None, port=0, unix_socket=None,charset='', sql_mode=None,read_default_file=None, conv=None, use_unicode=None,client_flag=0, cursorclass=Cursor, init_command=None,connect_timeout=10, ssl=None, read_default_group=None,compress=None, named_pipe=None, no_delay=None,autocommit=False, db=None, passwd=None, local_infile=False,max_allowed_packet=16*1024*1024, defer_connect=False,auth_plugin_map={}, read_timeout=None, write_timeout=None,bind_address=None, binary_prefix=False): View Code有幾個參數是必須的host、port、user、password、db
charset最好也要加上,否則無法識別中文!
?
二、execute()之sql注入
1、sql注入之:用戶存在,繞過密碼
格式:
存在的用戶名' -- 任意字符 或者 存在的用戶名' #任意字符注意:存在的用戶名后面,必須有一個單引號。--后面必須有一個空格
代碼依然保持不變,輸入一個已存在的用戶。
測試#
測試--
結果提示登錄成功
將sql復制到navicat軟件中執行,發現是有結果的。因為 --空格? 表示注釋。
?
2、sql注入之:用戶不存在,繞過用戶與密碼
格式:
任意用戶名' or 1=1 -- 任意字符 或者 任意用戶名' or 1=1 #任意字符注意:
1.任意用戶名后面必須有一個單引號,
2.必須有or關鍵字
3.必須保證等式成立,可以是2=2
4.--后面必須有空格
5.關鍵字or和等式之間,必須要有空格
先測試--
再測試#
將sql復制到navicat軟件中執行,發現是有結果的
?
因為1=1等式成立,直接忽略用戶名判斷,所以返回表中的所有數據
用戶表再增加一條數據,再次執行同樣的sql。它就是返回表中的所有數據。
?解決方法:?
# 原來是我們對sql進行字符串拼接 # sql="select * from userinfo where name='%s' and password='%s'" %(username,pwd) # print(sql) # result=cursor.execute(sql)#改寫為(execute幫我們做字符串拼接,我們無需且一定不能再為%s加引號了) sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引號,因為pymysql會自動為我們加上 result=cursor.execute(sql,[user,pwd]) #pymysql模塊自動幫我們解決sql注入的問題,只要我們按照pymysql的規矩來。查看execute源代碼
def execute(self, query, args=None):"""Execute a query:param str query: Query to execute.:param args: parameters used with query. (optional):type args: tuple, list or dict:return: Number of affected rows:rtype: intIf args is a list or tuple, %s can be used as a placeholder in the query.If args is a dict, %(name)s can be used as a placeholder in the query.""" View Code:type args: tuple, list or dict
看上面這句,類型可以是元組,列表,字典。下面分別演示!
元組
#導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()# 注意%s 表示占位符 sql = "select * from userinfo where username = %s and password = %s" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 result = cursor.execute(sql,(user,pwd)) print('返回記錄數:',result)# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('登陸成功') else:print('登錄失敗') View Code列表
#導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()# 注意%s 表示占位符 sql = "select * from userinfo where username = %s and password = %s" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 result = cursor.execute(sql,[user,pwd]) print('返回記錄數:',result)# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('登陸成功') else:print('登錄失敗') View Code字典
#導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()# 注意%(username)s 里面的username是字典的key,必須一一對應才行,否則報錯! sql = "select * from userinfo where username = %(username)s and password = %(password)s" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 result = cursor.execute(sql,{'username':user,'password':pwd}) print('返回記錄數:',result)# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('登陸成功') else:print('登錄失敗') View Code?
再次使用sql注入方式登錄,就會登錄失敗
?
三、增、刪、改:conn.commit()
commit()方法:在數據庫里增、刪、改的時候,必須要進行提交,否則插入的數據不生效。
增加
插入一條數據
#!/usr/bin/env python # -*- coding: utf-8 -*- #導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()sql = "insert into userinfo(username,password) values (%s,%s)" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 #插入一條數據 result = cursor.execute(sql,(user,pwd)) print('返回記錄數:',result)#一定記得commit conn.commit()# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('ok') else:print('error') View Code執行效果如下:
查看表記錄
同時插入多條數據
#導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()sql = "insert into userinfo(username,password) values (%s,%s)" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 #同時插入多條數據 result = cursor.executemany(sql,[(user+'1',pwd),(user+'2',pwd)]) print('返回記錄數:',result)#一定記得commit conn.commit()# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('ok') else:print('error') View Code執行效果如下:
查看表記錄
改
#!/usr/bin/env python # -*- coding: utf-8 -*- #導入模塊 import pymysqluser = input('請輸入用戶名:') pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()sql = "update userinfo set username = %s where id = '8'" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 #修改一條數據 result = cursor.execute(sql,user) print('返回記錄數:',result)#一定記得commit conn.commit()# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('ok') else:print('error') View Code執行效果如下:
?
查看表記錄
刪
#!/usr/bin/env python # -*- coding: utf-8 -*- #導入模塊 import pymysql#刪除不需要執行這2個input了 # user = input('請輸入用戶名:') # pwd = input('請輸入密碼:')# 1.連接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()sql = "delete from userinfo where id = '2'" print('sql語句:',sql)# 3.執行sql語句,返回sql查詢成功的記錄數 #刪除一條數據 result = cursor.execute(sql) print('返回記錄數:',result)#一定記得commit conn.commit()# 關閉連接,游標和連接都要關閉 cursor.close() conn.close()#判斷結果 if result:print('ok') else:print('error') View Codeinput不需要執行了,直接注釋掉即可
執行效果如下:
查看表記錄
四、查:fetchone、fetchmany、fetchall
fetchone():獲取下一行數據,第一次為首行; fetchall():獲取所有行數據源 fetchmany(4):獲取4行數據查看一下表內容:
mysql> select * from userinfo; +----+-----------+----------+ | id | username | password | +----+-----------+----------+ | 1 | qiwei | 123 | | 6 | 高圓圓 | 123 | | 7 | 舒暢1 | 123 | | 8 | 劉思思 | 123 | +----+-----------+----------+ 4 rows in set (0.00 sec) View Code使用fetchone():
#導入模塊 import pymysql# 1.連接 conn = pymysql.connect(host='localhost', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()sql = 'select * from userinfo' cursor.execute(sql)# 查詢第一行的數據 row = cursor.fetchone() print(row) # (1, 'qiwei', '123')# 查詢第二行數據 row = cursor.fetchone() print(row) # (6, '高圓圓', '123')# 4.關閉游標 cursor.close()# 5.關閉連接 conn.close() View Code使用fetchall():
#導入模塊 import pymysql# 1.連接 conn = pymysql.connect(host='localhost', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor()sql = 'select * from userinfo' cursor.execute(sql)# 獲取所有的數據 rows = cursor.fetchall() print(rows)# 4.關閉游標 cursor.close()# 5.關閉連接 conn.close() View Code運行結果如下:
默認情況下,我們獲取到的返回值是元組,只能看到每行的數據,卻不知道每一列代表的是什么,這個時候可以使用以下方式來返回字典,每一行的數據都會生成一個字典:
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) #在實例化的時候,將屬性cursor設置為pymysql.cursors.DictCursor再次運行,結果如下:
[{'id': 1, 'username': 'qiwei', 'password': '123'}, {'id': 6, 'username': '高圓圓', 'password': '123'}, {'id': 7, 'username': '舒暢1', 'password': '123'}, {'id': 8, 'username': '劉思思', 'password': '123'}]
?
在fetchone示例中,在獲取行數據的時候,可以理解開始的時候,有一個行指針指著第一行的上方,獲取一行,它就向下移動一行,所以當行指針到最后一行的時候,就不能再獲取到行的內容,所以我們可以使用如下方法來移動行指針:
cursor.scroll(1,mode='relative') # 相對當前位置移動 cursor.scroll(2,mode='absolute') # 相對絕對位置移動 第一個值為移動的行數,整數為向下移動,負數為向上移動,mode指定了是相對當前位置移動,還是相對于首行移動舉例:
#導入模塊 import pymysql# 1.連接 conn = pymysql.connect(host='localhost', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)sql = 'select * from userinfo' cursor.execute(sql)# 查詢第一行的數據 row = cursor.fetchone() print(row) # {'password': '123', 'username': 'qiwei', 'id': 1}# 查詢第二行數據 row = cursor.fetchone() print(row) # {'username': '高圓圓', 'password': '123', 'id': 6}cursor.scroll(-1,mode='relative') #設置之后,光標相對于當前位置往前移動了一行,所以打印的結果為第二行的數據 row = cursor.fetchone() print(row) # {'id': 6, 'username': '高圓圓', 'password': '123'}cursor.scroll(0,mode='absolute') #設置之后,光標相對于首行沒有任何變化,所以打印的結果為第一行數據 row = cursor.fetchone() print(row) # {'id': 1, 'username': 'qiwei', 'password': '123'}# 4.關閉游標 cursor.close()# 5.關閉連接 conn.close() View Code執行結果為:
?
?fetchmany():
#導入模塊 import pymysql# 1.連接 conn = pymysql.connect(host='localhost', port=3306, user='root', password='', db='db2', charset='utf8')# 2.創建游標 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)sql = 'select * from userinfo' cursor.execute(sql)# 獲取2條數據 rows = cursor.fetchmany(2) print(rows)# 4.關閉游標 cursor.close()# 5.關閉連接 conn.close() View Code執行結果為:
[{'id': 1, 'username': 'qiwei', 'password': '123'}, {'id': 6, 'username': '高圓圓', 'password': '123'}]
?
轉載于:https://www.cnblogs.com/xiao987334176/p/9182976.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python 全栈开发,Day63(子查询,MySQl创建用户和授权,可视化工具Navicat的使用,pymysql模块的使用)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解全局免流原理(转载)
- 下一篇: linux cmake编译源码,linu