如何使用Django Rest Framework读取CSV、EXL文件并存储到模型
用Python内置CSV模块与openpyxl实现文件读取+数据库去重存储
核心思路
实现需求的关键是确定数据的唯一标识字段(如用户ID、订单号这类不会重复的字段),读取文件数据后先查询数据库中已存在的标识,过滤重复数据后再插入。以下分CSV和XLS/XLSX两种文件类型给出具体实现:
1. 处理CSV文件(内置csv模块)
以SQLite数据库为例(切换MySQL/PostgreSQL仅需修改连接代码),假设唯一标识字段为user_id。
代码实现
import csv import sqlite3 # 数据库连接 conn = sqlite3.connect('data.db') cursor = conn.cursor() # 创建目标表(不存在则创建) cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( user_id TEXT PRIMARY KEY, name TEXT, email TEXT ) ''') # 读取数据库中已存在的唯一标识,存入集合提升查询效率 existing_ids = set(row[0] for row in cursor.execute('SELECT user_id FROM users')) # 读取CSV文件并过滤重复数据 with open('data.csv', 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: user_id = row['user_id'] if user_id not in existing_ids: cursor.execute(''' INSERT INTO users (user_id, name, email) VALUES (?, ?, ?) ''', (user_id, row['name'], row['email'])) existing_ids.add(user_id) # 更新集合,避免循环内重复判断 conn.commit() conn.close()
关键说明
- 给唯一标识字段设置
PRIMARY KEY约束,即使代码层判断遗漏,数据库也会拒绝重复插入 - 用集合存储已存在标识,查询效率远高于每次查询数据库
csv.DictReader通过列名获取数据,可读性更强
2. 处理XLS/XLSX文件(openpyxl模块)
同样以SQLite为例,唯一标识字段为user_id。
代码实现
import openpyxl import sqlite3 # 数据库连接 conn = sqlite3.connect('data.db') cursor = conn.cursor() # 确保目标表存在 cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( user_id TEXT PRIMARY KEY, name TEXT, email TEXT ) ''') # 获取已存在的唯一标识 existing_ids = set(row[0] for row in cursor.execute('SELECT user_id FROM users')) # 读取Excel文件 wb = openpyxl.load_workbook('data.xlsx') ws = wb.active # 读取第一个工作表 # 跳过表头(假设第一行为表头),遍历数据行 for row in ws.iter_rows(min_row=2, values_only=True): user_id, name, email = row if user_id not in existing_ids: cursor.execute(''' INSERT INTO users (user_id, name, email) VALUES (?, ?, ?) ''', (user_id, name, email)) existing_ids.add(user_id) conn.commit() conn.close()
关键说明
iter_rows(min_row=2, values_only=True)跳过表头,直接获取行数据元组- 若Excel有多个工作表,可通过
wb['工作表名称']指定读取目标 - 同样依赖数据库
PRIMARY KEY做最后一步去重保障
通用去重优化方案
- 若数据量极大,不要一次性读取所有已存在标识到内存,可采用分批查询或数据库批量对比(如
WHERE user_id IN (...)) - 针对MySQL等数据库,可使用
INSERT ... ON DUPLICATE KEY UPDATE语法,直接在数据库层面处理重复数据(无需提前查询),示例:
INSERT INTO users (user_id, name, email) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE name=VALUES(name), email=VALUES(email);
该语句会在主键重复时更新现有数据,而非报错。
内容的提问来源于stack exchange,提问作者Roharsh Joy
相关产品推荐
相关产品推荐

