学习的过程中总是能遇到各种各样的问题
清理手机号重复的数据,但要求,每个手机号 留存 3条
思路
- 首先手机号分组查询,每次查询 100 组(也就是把手机号相同的数据 归纳到一起,并按照重复数量降序,取前 100个不相同手机号)
- 根据手机号获取对应手机号的所有 id
- 保留前三个 id,删除多余的数据
思路有了动手吧!
config.ini
通用的配置信息,按个人习惯使用
[config]
auth = Eitaqx@163.com
version = 1.0.0
desc = config.ini # 仅用来保存配置信息
[sql_link] # 数据库连接信息
host = mysql.rds.yun.com
database = mysql
user = root
password = 123456
port = 3306
config.py
配置模块,只是为了 获取 .ini 中配置信息
import configparser
config = configparser.ConfigParser()
config.read('./config/config.ini', encoding='utf-8')
class Config:
"""
用来设置/获取配置信息
"""
global config
@staticmethod
def get(name='config'):
"""
:params name
:return dictionary
获取指定的配置信息
"""
dictionary = {}
for v in config.items(name):
dictionary[v[0]] = v[1]
return dictionary
....
删除程序,注意:sql执行失败回滚,异常处理,连接超时等
没有做处理
# -*- coding: utf-8 -*-
import pymysql
from config.index import Config
config = Config()
class RemoveRepeatMobile:
global config
def __init__(self):
self.connect()
self.limit = 100
self.run()
def connect(self):
"""
连接数据库
"""
sql_link = {
**config.get('sql_link'),
"cursorclass": pymysql.cursors.DictCursor,
'port': int(config.get('sql_link')['port'])
}
self.db = pymysql.connect(**sql_link)
self.cursor = self.db.cursor()
print(':::数据库连接成功!')
def run(self):
"""
处理重复手机号流程
"""
mobile_list = self.checked_mobile()
for v in mobile_list:
if v['count'] > 3:
id = self.select_mobile_id(v['mobile'])
self.remove_repeat_info(id, v['mobile'])
else:
print(f":::{v['mobile']}:{v['count']}条")
self.run()
def checked_mobile(self):
"""
:return list
分组查询重复手机号,并统计相应手机号重复次数
"""
print(':::正在查询数据...')
self.cursor.execute(f"SELECT mobile, id, COUNT(*) as count from infolist GROUP BY mobile ORDER BY count DESC LIMIT {self.limit}")
group = self.cursor.fetchall()
print(':::查询数据成功...')
if group[0]['count'] <= 3:
print(":::删除数据结束")
exit()
return group
def select_mobile_id(self, mobile):
"""
:params mobile
:reurn list
获取重复手机id(前3条信息除外),并返回id列表
"""
print(':::获取重复手机id(前3条信息除外)')
# SELECT id from infolist WHERE mobile={mobile} ORDER BY id ASC
# 这样就可以取到 同一手机号 下的所有 id 了然后在针对每个 id 进行删除
# 然而跑起来,却是 半天才能处理一个 手机号,突然
# 程序刚跑起来,又想到,为什么要获取同一手机号所有的 id 呢,我只要按顺序采集 获取 3条 不就满足条件了吗
# 我只需要按照 手机号 和 id 大于 第 三条 不就可以满足条件了吗,当然第3条也是可以的
# SELECT id from infolist WHERE mobile={mobile} ORDER BY id ASC LIMIT 2,1
self.cursor.execute(f"SELECT id from infolist WHERE mobile={mobile} ORDER BY id ASC LIMIT 3")
mobile_list = self.cursor.fetchall()
print(f'需要删除数量:{len(mobile_list)-3}')
return mobile_list[2]['id']
def remove_repeat_info(self, id, mobile):
print(id, mobile)
print(f":::正在删除手机号:{mobile}")
# 刚开始使用
# for v in ids:
# self.cursor.execute(f"DELETE FROM infolist WHERE id={v}")
# self.db.commit()
# 结果,,,等了很久才处理了一个 2.6万条重复 手机号 的数据,
# 之后想到,如果手机号确定,按照 id 进行排序
# 这样 我只要删除 小于 第三个 id 的这样是不是就很快了
# 修改了程序之后果然很快了
self.cursor.execute(f"DELETE FROM infolist WHERE mobile={mobile} AND id>{id}")
self.db.commit()
print(":::删除一组成功")
if __name__ == "__main__":
RemoveRepeatMobile()