CSV导入Django SQLite及合并员工签到签退记录的代码求助
嘿,我来帮你搞定这两个Django数据导入的问题!先理清楚思路,咱们一步步来:
Django CSV 导入与员工签到签退记录合并方案
先确认你的Employee模型结构
首先得保证models.py里的Employee类能存下咱们需要的字段——毕竟要每个员工一行,得包含签到、签退时间这些信息,给你个示例:
# models.py from django.db import models class Employee(models.Model): employee_id = models.CharField(max_length=50, unique=True, verbose_name="员工ID") name = models.CharField(max_length=100, verbose_name="员工姓名") time_in = models.DateTimeField(null=True, blank=True, verbose_name="签到时间") time_out = models.DateTimeField(null=True, blank=True, verbose_name="签退时间") def __str__(self): return self.name
需求1:基础CSV导入(适配你已有的import.py)
既然你已经在用import.py导入数据,先给你一个标准的基础版本,确保能把CSV数据正确导入SQLite:
# import.py(基础版) import csv import os import django # 先初始化Django环境,替换成你的项目名 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings") django.setup() # 替换成你的app名 from your_app_name.models import Employee def import_csv(file_path): with open(file_path, 'r', encoding='utf-8') as csv_file: # 用DictReader可以通过列名读取数据,更直观 reader = csv.DictReader(csv_file) for row in reader: # 假设你的CSV列是employee_id, name, time_type, record_time # get_or_create确保不会重复创建同一员工 employee, created = Employee.objects.get_or_create( employee_id=row['employee_id'], defaults={'name': row['name']} ) # 分别赋值签到/签退时间 if row['time_type'] == 'timein': employee.time_in = row['record_time'] elif row['time_type'] == 'timeout': employee.time_out = row['record_time'] employee.save() if __name__ == "__main__": # 替换成你的WorkNames.csv路径 import_csv('WorkNames.csv')
需求2:合并同一员工的签到签退记录
接下来解决核心问题——让每个员工在数据库里只存一行数据,给你两种方案:
方案1:导入WorkNames.csv时直接合并两条记录
这个方案不需要额外处理CSV,直接在导入脚本里把同一个员工的签到、签退记录合并,修改你的import.py就行:
# import.py(方案1:导入时合并) import csv import os import django from collections import defaultdict os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings") django.setup() from your_app_name.models import Employee def import_and_merge_csv(file_path): # 先用字典按员工ID分组,把同一个员工的两条记录整合到一起 employee_data = defaultdict(dict) with open(file_path, 'r', encoding='utf-8') as csv_file: reader = csv.DictReader(csv_file) for row in reader: emp_id = row['employee_id'] # 先存员工姓名 if 'name' not in employee_data[emp_id]: employee_data[emp_id]['name'] = row['name'] # 分别存储签到、签退时间 if row['time_type'] == 'timein': employee_data[emp_id]['time_in'] = row['record_time'] elif row['time_type'] == 'timeout': employee_data[emp_id]['time_out'] = row['record_time'] # 现在把整合好的数据导入数据库 for emp_id, data in employee_data.items(): # update_or_create:员工存在就更新时间,不存在就新建 Employee.objects.update_or_create( employee_id=emp_id, defaults={ 'name': data['name'], 'time_in': data.get('time_in'), # 用get避免KeyError,没有的话留空 'time_out': data.get('time_out') } ) if __name__ == "__main__": import_and_merge_csv('WorkNames.csv')
小提示:如果你的CSV时间格式和Django的DateTimeField不兼容,可能需要用datetime.strptime()先转换格式,比如datetime.strptime(row['record_time'], '%Y-%m-%d %H:%M:%S')
方案2:从已处理好的output.csv导入
如果你已经通过其他方式(比如Excel的合并功能、单独的脚本)把WorkNames.csv转换成了每行一个员工的output.csv,那导入代码会更简单:
# import.py(方案2:导入output.csv) import csv import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings") django.setup() from your_app_name.models import Employee def import_processed_csv(file_path): with open(file_path, 'r', encoding='utf-8') as csv_file: reader = csv.DictReader(csv_file) for row in reader: # 假设output.csv的列是employee_id, name, time_in, time_out Employee.objects.update_or_create( employee_id=row['employee_id'], defaults={ 'name': row['name'], 'time_in': row['time_in'], 'time_out': row['time_out'] } ) if __name__ == "__main__": import_processed_csv('output.csv')
这个方案适合你已经提前处理好CSV的情况,直接导入就能保证每个员工只有一行数据。
内容的提问来源于stack exchange,提问作者Ashish
相关产品推荐
相关产品推荐

