目录
一、问题起源
二、问题的解决
三、总结
一、问题起源
最近在做数据分析,在本机调试的时候,使用pymysql无法连接mysql,返回提示 MySQL DB Connect Error :2003: Can't connect to MySQL server on '192.168.2.3' ([WinError 10061] 由于目标计算机积极拒绝,无法连接。)但是用SQLyog之类的工具可以连接,这是什么情况呢?
项目中定义了一个连接mysql的类,主要实现方法pymysql.connect(host=host, user=user, passwd=passwd, db=db, port=3306, charset='utf8')
class PyMySQL:
# 获取当前时间
def getCurrentTime(self):
return time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime(time.time()))
# 数据库初始化
def _init_(self, host, user, passwd, db, port=3306, charset='utf8'):
pymysql.install_as_MySQLdb()
try:
self.db = pymysql.connect(host=host, user=user, passwd=passwd, db=db, port=3306, charset='utf8')
# self.db = pymysql.connect(ip, username, pwd, schema,port)
self.db.ping(True) # 使用mysql ping来检查连接,实现超时自动重新连接
print(self.getCurrentTime(), u"MySQL DB Connect Success:", user + '@' + host + ':' + str(port) + '/' + db)
self.cur = self.db.cursor()
except Exception as e:
print(self.getCurrentTime(), u"MySQL DB Connect Error :%d: %s" % (e.args[0], e.args[1]))
# 插入数据
def selectData(self,ssql,itype = 1):
try:
try:
mycursor = self.db.cursor(cursor=pymysql.cursors.DictCursor)
mycursor.execute(ssql)
myresult = mycursor.fetchall()
return myresult
finally:
mycursor.close()
except Exception as e:
print(self.getCurrentTime(), u"MySQLdb Error: %s" % (e))
return '0'
def insertData(self, table, my_dict,inserttype='replace into'):
try:
# 增加了插入数据时候的类型选择
# self.db.set_character_set('utf8')
# 存在 不存在
# insert ignore 忽略 插入
# insert into 报错 插入
# replace into 替换 插入
# self.db.set_character_set('utf8')
cols = ','.join(my_dict.keys())
values = '","'.join(my_dict.values())
# if table == 'fund_managers_chg':
# sql = "insert into %s (%s) values (%s)" % (table, cols, '"' + values + '"')
# else:
sql = inserttype + " %s (%s) values (%s)" % (table, cols, '"' + values + '"')
try:
result = self.cur.execute(sql)
insert_id = self.db.insert_id()
self.db.commit()
# 判断是否执行成功
if result:
# print (self.getCurrentTime(), u"Data Insert Sucess")
return insert_id
else:
return 0
except Exception as e:
# 发生错误时回滚
self.db.rollback()
print(self.getCurrentTime(), u"Data Insert Failed: %s" % (e))
return 0
except Exception as e:
print(self.getCurrentTime(), u"MySQLdb Error: %s" % (e))
return 0
# 查询并分析数据
# def getCurrDatas(self):
# pymysql.install_as_MySQLdb()
# try:
#
# except Exception as e:
[2022-11-26 10:21:13] MySQL DB Connect Error :2003: Can't connect to MySQL server on '192.168.2.3' ([WinError 10061] 由于目标计算机积极拒绝,无法连接。)
二、问题的解决
首先尝试着授权:
MYSql代码
GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
FLUSH PRIVILEGES
注意授权后必须FLUSH PRIVILEGES否则无法立即生效。
然而一波未平一波又起,执行的时候返回了错误
错误代码: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'password' WITH GRANT OPTION' at line 1
本质上的原因是MYSQL的新版本不支持这样授权了
修正后的语句:分开三次执行
#创建账户
create user 'root'@'172.16.10.203' identified by 'password'
#赋予权限,with grant option这个选项表示该用户可以将自己拥有的权限授权给别人
grant all privileges on *.* to 'root'@'172.16.10.203' with grant option
#改密码&授权超用户,flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设置从mysql库(MySQL数据库的内置库)中提取到内存里
flush privileges;
操作了一番后,结果还是一样无法连接。
转念一想是不是pymysql的问题呢 ?于是跟踪进入pymysql的connections.py单元。
发现问题所在,明明我为了安全,把mysql端口号改为了别的, 但是连接时候真正跟踪到的还是那个默认的3306
往上级自己封装的单元一查,原来port不小心固定写了3306,困扰了几天的事情原来是个大乌龙。
try:
self.db = pymysql.connect(host=host, user=user, passwd=passwd, db=db, port=3306, charset='utf8')
# self.db = pymysql.connect(ip, username, pwd, schema,port)
self.db.ping(True) # 使用mysql ping来检查连接,实现超时自动重新连接
print(self.getCurrentTime(), u"MySQL DB Connect Success:", user + '@' + host + ':' + str(port) + '/' + db)
self.cur = self.db.cursor()
except Exception as e:
print(self.getCurrentTime(), u"MySQL DB Connect Error :%d: %s" % (e.args[0], e.args[1]))
三、总结
Mysql分配权限各个版本的语句不同,需要根据不同的mysql版本采用不同的分配权限的方式。大家根据真实的使用场景赋值不同的权限,root账户尽量少对外使用。需要提供给外部使用的可以重新create user创建个新用户专门对外。端口也建议更换一个,不要用3306,同时记得以前固定用3306的地方一定要做变量引入,不然就会遇到像我遇到的问题一样。查到最后发现是端口的问题