当前位置: 首页 > news >正文

MySQL 局域网部署实战:3 秒自动上传 + 自动补全 + 跨机查询(避坑指南)

本文重点是 六、避坑指南(核心重点!)的第四点:

mysql.connector 不兼容 MySQL 8.0 认证方式,或 DNS 反向解析超时,改用 PyMySQL;z

用局域网的另一台电脑访问本机MySQL数据时,用Navicat查询没问题,但是python代码查询时,不报错,也没有数据返回。其实时链接数据库是卡死了,直接退出了程序。

原因就是mysql.connector 的包不行,PyMySQL这个包可以。

一、需求背景

最近需要实现一个「局域网数据同步系统」,核心需求:

  1. 本机每 3 秒采集时间数据,写入 MySQL 数据库;
  2. 自动从时间字段中提取年 / 月 / 日,补全对应字段;
  3. 局域网内其他电脑可通过代码查询数据库,实时获取数据;
  4. 稳定不丢数据、不卡死、跨设备兼容。

最终实现了「3 件套」程序:自动上传 + 自动补全 + 跨机查询,全程踩了 N 个坑,特此整理成教程,帮大家少走弯路!

二、技术选型

工具 / 框架

选择理由

替代方案对比

MySQL 8.0

免费、稳定、支持局域网并发

SQLite(不支持网络共享)、Access(易损坏)

PyMySQL

Python 连接 MySQL 的稳定驱动

mysql.connector(局域网易卡死,不推荐)

Navicat

可视化管理数据库,方便调试

phpMyAdmin(网页版,操作繁琐)

关键选型逻辑:文件型数据库(SQLite/Access)不适合局域网频繁写入,直接选择 C/S 架构的 MySQL,从根源避免数据丢失、锁表问题。

三、前置准备

1. 环境配置

  • 服务器端(部署 MySQL):Windows 10/11 + MySQL 8.0
  • 客户端(查询 / 上传):Windows 10/11 + Python 3.8+
  • 网络:所有设备在同一局域网(路由器 / 交换机连接)

2. MySQL 基础配置

(1)安装 MySQL

推荐用 XAMPP 一键安装(免配置),或官网下载安装包,记住:

  • 主机:localhost(服务器本机)
  • 端口:3306(默认)
  • 用户名:root
  • 密码:自定义(本文示例用 123456)
(2)创建数据库和表

用 Navicat 连接本机 MySQL,执行以下 SQL:

-- 创建数据库(本文库名:hnx)

CREATE DATABASE IF NOT EXISTS hnx CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

-- 切换数据库

USE hnx;

-- 创建数据表(存储时间数据)

CREATE TABLE IF NOT EXISTS upload_data (

id INT PRIMARY KEY AUTO_INCREMENT, -- 自增ID

time_full VARCHAR(20) NOT NULL, -- 完整时间(格式:20250103123456)

year VARCHAR(4), -- 提取的年

month VARCHAR(2), -- 提取的月

day VARCHAR(2) -- 提取的日

);

四、核心程序实现(全套代码)

1. 程序 1:每 3 秒自动上传时间数据(服务器 / 本机)

功能:持续采集当前时间,写入 MySQL,支持后台运行。

# 安装依赖:pip install pymysql

import pymysql

import time

from datetime import datetime

# 配置信息(根据实际修改)

CONFIG = {

"host": "localhost", # 服务器本机IP(localhost/192.168.3.1)

"user": "root",

"password": "123456",

"database": "hnx",

"port": 3306,

"charset": "utf8mb4"

}

def connect_db():

"""创建数据库连接"""

return pymysql.connect(**CONFIG, connect_timeout=5)

def upload_time_data():

"""每3秒上传一次时间数据"""

conn = connect_db()

cursor = conn.cursor()

print("✅ 数据上传程序启动!每3秒上传一条数据(Ctrl+C停止)")

try:

while True:

# 获取当前时间(年月日时分秒)

time_full = datetime.now().strftime("%Y%m%d%H%M%S")

# 插入数据(只传完整时间,年/月/日后续自动补全)

sql = "INSERT INTO upload_data (time_full) VALUES (%s)"

cursor.execute(sql, (time_full,))

conn.commit()

print(f"✅ 上传成功 | 时间:{time_full}")

time.sleep(3)

except KeyboardInterrupt:

print("\n�� 程序手动停止")

finally:

cursor.close()

conn.close()

if __name__ == "__main__":

upload_time_data()

2. 程序 2:自动补全年 / 月 / 日(服务器 / 本机)

功能:扫描表中year为空的数据,从time_full提取年 / 月 / 日并补全。

import pymysql

import time

# 同上面的CONFIG配置

CONFIG = {

"host": "localhost",

"user": "root",

"password": "123456",

"database": "hnx",

"port": 3306,

"charset": "utf8mb4"

}

def connect_db():

return pymysql.connect(**CONFIG, connect_timeout=5)

def auto_fill_date():

print("✅ 自动补全年月日程序启动(PyMySQL版)")

print("�� 正在扫描需要补全的数据...\n")

while True:

try:

conn = connect_db()

cursor = conn.cursor()

# 1. 查询year为空的数据

select_sql = "SELECT id, time_full FROM upload_data WHERE year IS NULL OR year = ''"

cursor.execute(select_sql)

empty_data = cursor.fetchall()

if not empty_data:

print("⏳ 暂无需要补全的数据,10秒后重试...")

time.sleep(10)

continue

# 2. 逐条提取并更新

for data_id, time_full in empty_data:

if len(time_full) >= 8: # 确保时间格式正确

year = time_full[0:4] # 前4位:年

month = time_full[4:6] # 第5-6位:月

day = time_full[6:8] # 第7-8位:日

# 更新数据

update_sql = """

UPDATE upload_data

SET year = %s, month = %s, day = %s

WHERE id = %s

"""

cursor.execute(update_sql, (year, month, day, data_id))

conn.commit()

print(f"✅ 补全成功 | ID:{data_id} | {year}年{month}月{day}日")

cursor.close()

conn.close()

time.sleep(3) # 每3秒扫描一次

except Exception as e:

print(f"❌ 出错重试:{str(e)}")

time.sleep(3)

if __name__ == "__main__":

auto_fill_date()

3. 程序 3:局域网跨机查询数据(客户端)

功能:局域网内任意电脑,通过服务器 IP 查询数据库,显示所有数据。

import pymysql

# 配置信息(重点:host改为服务器IP)

CONFIG = {

"host": "192.168.3.1", # 服务器局域网IP(不是localhost!)

"user": "root",

"password": "123456",

"database": "hnx",

"port": 3306,

"charset": "utf8mb4"

}

def connect_db():

return pymysql.connect(**CONFIG, connect_timeout=5)

def query_data():

try:

conn = connect_db()

cursor = conn.cursor()

# 查询所有数据(按ID排序)

query_sql = "SELECT id, time_full, year, month, day FROM upload_data ORDER BY id ASC"

cursor.execute(query_sql)

all_data = cursor.fetchall()

# 格式化输出

print("=" * 70)

print("�� 局域网MySQL查询结果(hnx.upload_data)")

print("=" * 70)

for row in all_data:

data_id, time_full, year, month, day = row

print(f"ID:{data_id:>3} | 完整时间:{time_full} | 年:{year or '未填'} | 月:{month or '未填'} | 日:{day or '未填'}")

print(f"\n✅ 共查询到 {len(all_data)} 条数据")

cursor.close()

conn.close()

except Exception as e:

print(f"❌ 查询失败:{str(e)}")

if __name__ == "__main__":

query_data()

五、关键配置:让 MySQL 支持局域网访问

这是跨机查询的核心,少一步都不行!

1. 授权局域网用户访问

在服务器端(部署 MySQL 的电脑),用 Navicat 执行以下 SQL:

-- 允许root用户从任意局域网IP访问(%表示所有IP)

CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '123456';

-- 授予所有权限(生产环境可限制权限,测试用全开)

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';

-- 刷新权限

FLUSH PRIVILEGES;

-- 关键:修改认证方式(解决Python连接卡死)

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

FLUSH PRIVILEGES;

2. 开放 MySQL 3306 端口(防火墙)

服务器端必须开放 3306 端口,否则客户端连不上:

方法 1:图形界面(推荐)

1.按 Win+R → 输入wf.msc→ 打开「高级防火墙」;

2.左侧「入站规则」→ 右侧「新建规则」;

3.选择「端口」→ 下一步;

4.协议选 TCP → 特定本地端口填 3306 → 下一步;

5.选择「允许连接」→ 下一步;

6.勾选「专用 / 公用 / 域」→ 下一步;

7.名称填「MySQL 3306」→ 完成。

方法 2:命令行(管理员模式)

New-NetFirewallRule -DisplayName "MySQL 3306" -Direction Inbound -Protocol TCP -LocalPort 3306 -Action Allow

3. 关闭 MySQL DNS 反向解析(可选,解决卡死)

这是AI给的方法,这一步我没有操作,也实现了功能。

如果客户端连接仍卡死,修改 MySQL 配置文件my.ini(通常在ProgramData\MySQL\MySQL Server 8.0\):

# 新增一行,关闭DNS反向解析

skip_name_resolve

保存后,重启 MySQL 服务(服务面板找到 MySQL → 重启)。

六、避坑指南(核心重点!)

全程踩了 8 个坑,整理成「问题 - 原因 - 解决方案」,直接对照解决:

重点是第四点:

mysql.connector 不兼容 MySQL 8.0 认证方式,或 DNS 反向解析超时,改用 PyMySQL;

问题现象

根本原因

解决方案

报错no such table: upload_data

表未创建,或数据库名错误

1. 执行建表 SQL;2. 确认代码中database参数正确

报错NameError: name 'conn' is not defined

连接失败时,conn未初始化就关闭

提前定义conn = None,关闭前判断if conn is not None

写入成功但查询为空

1. 数据库名错误(如误用系统库mysql);2. 写入未 commit

1. 确认代码中database是自己建的库;2. 插入后执行conn.commit()

客户端 Navicat 能连,Python 卡死不报错

mysql.connector 不兼容 MySQL 8.0 认证方式,或 DNS 反向解析超时

1. 改用 PyMySQL;2. 执行ALTER USER修改认证方式;3. 关闭 DNS 反向解析

报错module 'pymysql' has no attribute 'connect'

文件名或目录下有pymysql.py,覆盖了真实库

重命名文件(如改为mysql_query.py),删除__pycache__文件夹

局域网连接失败TimeoutError

服务器防火墙未开放 3306 端口

按步骤开放 3306 端口,或临时关闭防火墙测试

报错Access denied for user 'root'@'xxx.xxx.xxx.xxx'

未授权局域网用户访问

执行授权 SQL(CREATE USER+GRANT

补全程序提取年 / 月 / 日错误

时间格式长度不足 8 位

代码中添加if len(time_full) >=8判断,确保格式正确

七、最终效果

  1. 服务器端运行「上传程序」+「补全程序」:
    • 每 3 秒生成一条时间数据;
    • 自动补全年 / 月 / 日,日志实时输出;
  1. 局域网客户端运行「查询程序」:
    • 秒连数据库,显示所有数据;
    • 无卡死、无报错、数据实时同步。

八、扩展建议

  1. 生产环境优化:
    • 给 MySQL 用户分配最小权限(不用ALL PRIVILEGES);
    • 定期备份数据库(避免数据丢失);
    • 限制上传频率(根据需求调整sleep时间);
  1. 功能扩展:
    • 增加数据导出 Excel 功能;
    • 加入异常邮件提醒;
    • 打包成 exe 文件(用 PyInstaller),双击运行;
  1. 替代方案:
    • 若不想用 MySQL,可选择 PostgreSQL(更稳定);
    • 若需跨互联网访问,可配置端口映射 + 动态域名。

总结

这套方案的核心是「放弃文件型数据库,选择 C/S 架构的 MySQL」,从根源解决局域网数据同步的稳定性问题。全程最关键的是「MySQL 局域网授权 + 防火墙端口开放 + PyMySQL 驱动选择」,避开这三个坑,基本就能一次成功。

所有代码都经过实测,直接复制修改配置即可运行,希望能帮大家少走弯路!如果遇到其他问题,欢迎在评论区交流~

(注:文档部分内容可能由 AI 生成)

http://www.jsqmd.com/news/663464/

相关文章:

  • 【仅限首批500名开发者获取】:基于eBPF+Code LLM构建的实时自愈沙箱环境,含3套生产级Prompt Chain模板与AST级错误注入测试套件
  • 避开运放电路设计坑:手把手教你用Altium Designer和Multisim验证电压抬升与放大
  • Python实战:从无序点云到结构化Mesh的自动化重建
  • python语法-------strptime + strftime + timedelta 终极区分(一次看懂)
  • 智能代码生成与审查自动化双引擎实践(2024企业级落地白皮书首发)
  • C# + SQL Server 从零到实战:从SQL入门到音乐播放器完整开发之路
  • 反射光电管ITR9909驱动能力不够?试试这颗达林顿管BC517
  • Winhance中文版:Windows系统优化的终极解决方案,免费提升电脑性能与个性化体验
  • 从SX1278到SX1262:手把手教你升级老旧LoRa模块,并实测功耗与传输距离变化
  • WorkshopDL:免费下载Steam创意工坊模组的终极解决方案
  • 构建高精度无人机编队控制仿真系统的工程实践
  • 做 GEO 之前要准备哪些资料:基础信息、内容素材与信号资产清单
  • 告别UNet!用Mirror Networking在Unity 2022 LTS里快速搭建你的第一个多人坦克对战Demo
  • 仅限奇点大会注册参会者获取的检测模型权重+训练数据集(含127万对人工标注克隆样本):AI代码克隆检测从入门到合规上线的7天闭环路径
  • W5500 MACRAW模式实战:在ESP32上抓取并解析原始以太网数据包
  • 别再用Excel硬扛了!用Python的sklearn库5分钟搞定PCA降维(附实战代码)
  • WIN7最新的Chrome内核浏览器
  • 表单django
  • STM32 HAL库RTC配置实战:从CubeMX到解决F1系列掉电日期丢失
  • 5大核心功能揭秘:AKShare财经数据获取的完整实战指南
  • Windows右键菜单的“数字园艺师“:ContextMenuManager深度解析与实战手册
  • 武昌老酒回收电话
  • 避坑指南:在Arduino IDE 1.8.x中编译STM32 Marlin固件报错‘attachInterrupt’的解决方法
  • SSH Client推荐集
  • 手办管理系统|基于springboot + vue手办商城系统(源码+数据库+文档)
  • HC32F460 FPU实战:从零开启硬件浮点加速
  • 从心跳到监护——CANOpen网络管理实战解析
  • 实用CLI工具:命令行下的高效选择
  • LCD1602自定义字符避坑指南:为什么你的5x7点阵汉字显示不全?
  • Android应用调试利器——Fiddler抓包实战全解析