Python系列四--對MySQL操作,問題匯總

前言:本次實驗基于Python3.5,很多問題都是可以用debug調(diào)試出來的

Python 操作MySQL流程

Python 操作MySQL流程.png

1、運行結(jié)果中文顯示亂碼

中文顯示亂碼.png

具體方法如下:

1)MySQL數(shù)據(jù)庫charset=utf-8
Paste_Image.png
2)Python文件設(shè)置編碼 utf-8 ,在文件前面加上一下代碼
 # -*- coding: utf-8 -*-
3)Python連接MySQL時加上參數(shù) charset=utf8
conn = pymysql.connect(host='localhost', port=3306, user='root',
                       passwd='123456', db='zyptest', charset='utf8')
4)設(shè)置Python的默認(rèn)編碼為 utf-8 (sys.setdefaultencoding(utf-8)

設(shè)置路徑:Pycharm軟件,F(xiàn)ile--Settings--File and Code Templates--Python Script

設(shè)置編碼格式路徑.png

若想要結(jié)果以字典的方式輸出,有2種方式(此方法不適用python3.6),代碼如下

  • 在 connection 的地方加上 cursorclass = pymysql.cursors.DictCursor
conn = pymysql.connect(host='localhost', port=3306, user='root',
                       passwd='123456Aa', db='zyptest', charset='utf8',
                       cursorclass = pymysql.cursors.DictCursor)
  • 創(chuàng)建游標(biāo)時指定
conn = pymysql.connect(host='localhost', port=3306, user='root',
                       passwd='123456Aa', db='zyptest', charset='utf8')
cur = conn.cursor(cursorclass=pymysql.cursors.DictCursor)  


2、使用IP地址連接mysql數(shù)據(jù)庫服務(wù)時提示“1130-host 'LAPTOP OOR4C 1HG' is not allowed to connect to this MySql server”

(pymql.connection 使用 host 使用 localhost 表達(dá)時調(diào)試沒有問題)

使用IT地址報錯.png

解決辦法
(1)改表法。
可能是你的帳號不允許從遠(yuǎn)程登陸,只能在localhost

mysql> use mysql;
mysql> select host,user from user;   
mysql> update user set host='%' where user='root' and host='localhost';

提醒:如果方法一解決不了你的問題,那還是先把user表中的host字段值改回去,再試試方法二

(2)授權(quán)法
Sql代碼(此處需要根據(jù)實際情況修改用戶(root)和密碼(123456)信息)

mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;      //授權(quán)
mysql>flush privileges;      //刷新權(quán)限,不需要重啟


3、使用云服務(wù)器的IP地址連接mysql數(shù)據(jù)庫服務(wù)時提示“ConnectionRefusedError: [WinError 10061] 由于目標(biāo)計算機積極拒絕,無法連接。”

使用云服務(wù)器的IP地址連接報錯.png

原因分析:安裝mariadb時禁止了遠(yuǎn)程登錄

解決辦法:重新設(shè)置,允許遠(yuǎn)程登錄(詳情見之前安裝的文章)

1、找到mysql的配置文件my.cnf,使用命令 find / -name "*my.cnf"
2、在my.cnf文件的 [mysqld] 后加入skip-grant-tables,保存文件
3、重啟mysql服務(wù) service mysql restart
4、重新登錄mysql (直接輸入mysql,不需要密碼)
5、修改密碼

use mysql;
update user set password=PASSWORD("密碼") where user='root';”(修改root的密碼)

6、再把配置文件的my.cnf 加入的skip-grant-tables刪除保存,或者 前面加上 #
7、重啟mysql服務(wù) (mysqld -restart)
8、重新登錄(使用密碼登錄,mysql -uroot -p)


4、運行正常,但沒有結(jié)果輸出

OperationDbInterface 被封裝成了類,此時叫做方法,想要調(diào)用的話需要實例化類。
(不封裝叫函數(shù))

if _name_ == "_main" (此處是2個下劃線)
在句子開始處加上if,就說明,這個句子是一個條件語句
_name_:作為模塊的內(nèi)置屬性,就是.py文件的調(diào)用方式
_main_:.py文件有兩種使用方式:作為模塊被調(diào)用和直接使用。如果它等于 "_main_" 就表示是直接執(zhí)行
在 if _name
== "_main_" :之后的語句作為模塊被調(diào)用的時候,語句之后的代碼不執(zhí)行;直接使用的時候,語句之后的代碼執(zhí)行。通常,此語句用于模塊測試中使用。

貼上源代碼

import pymysql
import os
import logging


class OperationDbInterface(object):     # 聲明類
    def __init__(self):
        self.conn = pymysql.connect(host='localhost', port=3306, user='root',
                                    passwd='123456', db='mysql', charset='utf8')
        self.cur = self.conn.curror()   # 創(chuàng)建游標(biāo)

    # 定義單條數(shù)據(jù)操作,增刪改
    def op_sql(self, param):
        try:
            self.cur.execute(param)  # 執(zhí)行sql語句
            self.conn.commit()
            return True
        except pymysql.Error as e:
            print("Mysql Error %d: %s" % (e.args[0], e.args[1]))
            logging.basicConfig(filename=os.path.join(os.getcwd(), './log.txt'),
                                level=logging.DEBUG,
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %     (levelname)s %(message)s')
            logger = logging.getLogger(__name__)
            logger.exception(e)
            return False

    # 查詢表中單條數(shù)據(jù)
    def selectone(self, condition):
        try:
            self.cur.execute(condition)
            results = self.cur.fetchone()   # 獲取一條數(shù)據(jù)
        except pymysql.Error as e:
            results = 'sql0001'  # 數(shù)據(jù)庫執(zhí)行錯誤
            print("Mysql Error %d: %s" % (e.args[0], e.args[1]))
            logging.basicConfig(filename=os.path.join(os.getcwd(), './log.txt'),
                                level=logging.DEBUG,
                                format='%(asctime)s %(filename)s[line:%(lineno)d] % (levelname)s %(message)s')
            logger = logging.getLogger(__name__)
        logger.exception(e)
        finally:
            return results

    # 查詢表中多條數(shù)據(jù)
    def selectall(self, conditon):
        try:
            self.cur.execute(conditon)
            self.cur.scroll(0, mode='absolute')     # 光標(biāo)回到初始位置
            results = self.cur.fetchall()    # 返回游標(biāo)中所有結(jié)果
        except pymysql.Error as e:
            results = 'sql0001'  # 數(shù)據(jù)庫執(zhí)行錯誤
            print("Mysql Error %d: %s" % (e.args[0], e.args[1]))
            logging.basicConfig(filename=os.path.join(os.getcwd(), './log.txt'),
                                level=logging.DEBUG,
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
            logger = logging.getLogger(__name__)
            logger.exception(e)
        finally:
            return results

    # 定義表中插入多條數(shù)據(jù)操作
    def insertmore(self, condition):
        try:
            self.cur.executemany(condition)
            self.conn.commit()
            return True
        except pymysql.Error as e:
            results = 'sql0001'  # 數(shù)據(jù)庫執(zhí)行錯誤
            print("Mysql Error %d: %s" % (e.args[0], e.args[1]))
            logging.basicConfig(filename=os.path.join(os.getcwd(), './log.txt'),
                                level=logging.DEBUG,
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
            logger = logging.getLogger(__name__)
            logger.exception(e)
            return False

    # 判斷表是否存在
    def __del__(self):
        if self.cur is not None:
            self.cur.close()
        if self.conn is not None:
            self.conn.close()

if __name__ == '__main()__':
    test = OperationDbInterface()  # 實例化類
    result = test.selectone('select * from db')
    print(result)
運行無結(jié)果輸出.png

原因分析:main()多了括號,應(yīng)該是

if __name__ == '__main__':

改完之后運行報錯 “AttributeError: 'Connection' object has no attribute 'curror'”
根據(jù)錯誤提醒回到20行代碼檢查,發(fā)現(xiàn)是 cursor 拼錯了

Paste_Image.png

接著改好執(zhí)行發(fā)現(xiàn)結(jié)果出來了,但是仍有報錯信息(Python3.5正常沒有報錯,如下圖是3.6的報錯信息

備注:待解決

有結(jié)果輸出但仍報錯.png

5、執(zhí)行錯誤語句,生成日志文件,打開沒有內(nèi)容

cd9b03664b5d458d629cc33e5b618ff.png

檢查發(fā)現(xiàn) logging 用的是2.7的語法格式,用2.7調(diào)試報錯

723881941772656882.png

6、執(zhí)行插入語句時報錯

TypeError: insertmore() takes 2 positional arguments but 3 were given

執(zhí)行插入語句時報錯.png

原因分析:
executemany()方法是要傳兩個參數(shù),一個sql語句一個args(list),源碼中只有一個參數(shù)
解決辦法:函數(shù)中增加參數(shù) params

executemany()方法.png

7、執(zhí)行批量刪除語句時報錯

def deletemore(self, condition, params):
    try:
        self.cur.executemany(condition, params)   # executemany為批量操作,可以進行多行插入
        self.conn.commit()
        return True

if __name__ == "__main__":
    test = OperationDbInterface()  # 實例化類
result = test.deletemore("delete from student WHERE id in(6,7)")
print(result)
執(zhí)行批量刪除語句時報錯.png

原因分析:不管字段是str,還是int,或者其他類型,都需要使用 %s 傳遞參數(shù)的方式進行,正確如下

result = test.deletemore("delete from student WHERE id in(%s)",[6,7])
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 【MySQL】Linux下MySQL 5.5、5.6和5.7的RPM、二進制和源碼安裝 1.1BLOG文檔結(jié)構(gòu)圖 ...
    小麥苗DB寶閱讀 10,906評論 0 31
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,900評論 18 399
  • 1.MySQL是一個關(guān)系型數(shù)據(jù)庫管理系統(tǒng),由瑞典MySQL AB 公司開發(fā),目前屬于 Oracle 旗下產(chǎn)品。My...
    黃花菜已涼閱讀 4,669評論 3 60
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,724評論 19 139
  • 后來這首歌,聽過很多次,卻從來沒有理解歌詞所說的那種意境,直到我上了大學(xué),離開家鄉(xiāng)離開我生命中重要的人 ,才明白了...
    傾城_75a7閱讀 300評論 0 0

友情鏈接更多精彩內(nèi)容