From 5b32692e66743214f98e6c33528491f4f12a5284 Mon Sep 17 00:00:00 2001 From: xiaji Date: Thu, 8 Jan 2026 17:58:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0CSV=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=92=8C=E5=AF=BC=E5=85=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增generate_import_csv.py脚本用于生成和导入测试数据 更新README.md添加CSV数据导入指南 生成3个CSV文件并实现自动导入功能 --- README.md | 60 +++++++++++ generate_import_csv.py | 231 +++++++++++++++++++++++++++++++++++++++++ insight_record.csv | 11 ++ logs/app.log | 22 ++++ reading_record.csv | 16 +++ reading_type.csv | 6 ++ 6 files changed, 346 insertions(+) create mode 100644 generate_import_csv.py create mode 100644 insight_record.csv create mode 100644 reading_record.csv create mode 100644 reading_type.csv diff --git a/README.md b/README.md index 658e33d..a01ed4c 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,66 @@ python manage.py runserver python manage.py migrate ``` +## CSV数据导入指南 + +### 生成CSV文件 + +项目包含一个`generate_import_csv.py`脚本,用于生成符合数据库表结构的CSV文件并导入数据。 + +1. 生成CSV文件: + ```bash + python generate_import_csv.py + ``` + +2. 生成的CSV文件: + - `reading_type.csv` - 阅读记录类型 + - `insight_record.csv` - 感悟记录 + - `reading_record.csv` - 阅读记录 + +### CSV文件格式说明 + +#### reading_type.csv(阅读记录类型) +| 字段名 | 类型 | 说明 | +|-------|------|------| +| name | 字符串 | 阅读类型名称(如:书籍、文章、论文等) | + +#### insight_record.csv(感悟记录) +| 字段名 | 类型 | 说明 | +|-------|------|------| +| date | 日期 | 记录日期(格式:YYYY-MM-DD) | +| content | 文本 | 感悟内容 | + +#### reading_record.csv(阅读记录) +| 字段名 | 类型 | 说明 | +|-------|------|------| +| date | 日期 | 记录日期(格式:YYYY-MM-DD) | +| type_id | 整数 | 阅读类型ID(关联reading_type表的id字段) | +| title | 字符串 | 阅读标题 | +| source | 字符串 | 阅读来源 | +| progress | 字符串 | 阅读进度(如:已完成、进行中、未开始) | +| note | 文本 | 阅读笔记 | + +### 自定义CSV数据 + +你可以手动编辑生成的CSV文件,添加或修改数据,然后再次运行导入脚本将数据导入到数据库。 + +### 数据导入 + +脚本会自动将CSV数据导入到数据库中,导入流程: + +1. 清空ReadingType表的现有数据(避免类型ID冲突) +2. 导入ReadingType数据 +3. 导入InsightRecord数据 +4. 导入ReadingRecord数据 + +### 验证导入结果 + +可以使用Django shell查询数据库,验证数据是否正确导入: + +```bash +python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings'); import django; django.setup(); from core.models import ReadingType, InsightRecord, ReadingRecord; print('ReadingType数量:', ReadingType.objects.count()); print('InsightRecord数量:', InsightRecord.objects.count()); print('ReadingRecord数量:', ReadingRecord.objects.count()); print('ReadingType数据:', [rt.name for rt in ReadingType.objects.all()])" +``` + ## 生产部署 ### 使用Gunicorn + Nginx diff --git a/generate_import_csv.py b/generate_import_csv.py new file mode 100644 index 0000000..1c55dc3 --- /dev/null +++ b/generate_import_csv.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +CSV生成和Django ORM导入脚本 +""" + +import csv +import os +from pathlib import Path +from datetime import date +from faker import Faker +from loguru import logger + +# 初始化faker +fake = Faker('zh_CN') + +# 项目根目录 +BASE_DIR = Path(__file__).resolve().parent + +# 设置Django环境 +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings') +import django +django.setup() + +# 导入Django模型 +from core.models import ReadingType, InsightRecord, ReadingRecord + +# 生成ReadingType CSV +@logger.catch +def generate_reading_type_csv(): + """生成阅读记录类型CSV文件""" + csv_path = BASE_DIR / 'reading_type.csv' + + # 定义字段名,与数据库表字段一一对应 + fields = ['name'] + + # 生成模拟数据 + data = [ + ['书籍'], + ['文章'], + ['论文'], + ['报告'], + ['其他'] + ] + + # 写入CSV文件 + with open(csv_path, 'w', newline='', encoding='utf-8') as f: + writer = csv.writer(f) + writer.writerow(fields) + writer.writerows(data) + + logger.info(f"生成ReadingType CSV文件成功: {csv_path}") + return csv_path + +# 生成InsightRecord CSV +@logger.catch +def generate_insight_record_csv(): + """生成感悟记录CSV文件""" + csv_path = BASE_DIR / 'insight_record.csv' + + # 定义字段名,与数据库表字段一一对应 + fields = ['date', 'content'] + + # 生成模拟数据 + data = [] + for _ in range(10): + record_date = fake.date_between(start_date='-30d', end_date='today') + content = fake.paragraph(nb_sentences=3, variable_nb_sentences=True) + data.append([record_date, content]) + + # 写入CSV文件 + with open(csv_path, 'w', newline='', encoding='utf-8') as f: + writer = csv.writer(f) + writer.writerow(fields) + writer.writerows(data) + + logger.info(f"生成InsightRecord CSV文件成功: {csv_path}") + return csv_path + +# 生成ReadingRecord CSV +@logger.catch +def generate_reading_record_csv(): + """生成阅读记录CSV文件""" + csv_path = BASE_DIR / 'reading_record.csv' + + # 定义字段名,与数据库表字段一一对应 + fields = ['date', 'type_id', 'title', 'source', 'progress', 'note'] + + # 生成模拟数据 + data = [] + for _ in range(15): + record_date = fake.date_between(start_date='-30d', end_date='today') + type_id = fake.random_int(min=1, max=5) # 对应ReadingType的id + title = fake.sentence(nb_words=5, variable_nb_words=True) + source = fake.company() + progress = fake.random_element(['已完成', '进行中', '未开始']) + note = fake.paragraph(nb_sentences=2, variable_nb_sentences=True) + data.append([record_date, type_id, title, source, progress, note]) + + # 写入CSV文件 + with open(csv_path, 'w', newline='', encoding='utf-8') as f: + writer = csv.writer(f) + writer.writerow(fields) + writer.writerows(data) + + logger.info(f"生成ReadingRecord CSV文件成功: {csv_path}") + return csv_path + +# 导入ReadingType CSV到Django模型 +@logger.catch +def import_reading_type_csv(csv_path): + """将阅读记录类型CSV导入到Django模型""" + try: + logger.info(f"开始导入 {csv_path} 到ReadingType模型") + + # 清空现有数据 + ReadingType.objects.all().delete() + logger.info("已清空现有ReadingType数据") + + # 读取CSV文件并导入数据 + with open(csv_path, 'r', encoding='utf-8') as f: + # 跳过表头 + next(f) + + # 读取CSV数据并创建模型实例 + reader = csv.reader(f) + reading_types = [] + for row in reader: + name = row[0] + reading_types.append(ReadingType(name=name)) + + # 批量创建 + ReadingType.objects.bulk_create(reading_types) + + logger.info(f"导入成功,共插入 {len(reading_types)} 条记录") + + except Exception as e: + logger.error(f"导入失败: {e}") + +# 导入InsightRecord CSV到Django模型 +@logger.catch +def import_insight_record_csv(csv_path): + """将感悟记录CSV导入到Django模型""" + try: + logger.info(f"开始导入 {csv_path} 到InsightRecord模型") + + # 读取CSV文件并导入数据 + with open(csv_path, 'r', encoding='utf-8') as f: + # 跳过表头 + next(f) + + # 读取CSV数据并创建模型实例 + reader = csv.reader(f) + insight_records = [] + for row in reader: + record_date = row[0] + content = row[1] + insight_records.append(InsightRecord(date=record_date, content=content)) + + # 批量创建 + InsightRecord.objects.bulk_create(insight_records) + + logger.info(f"导入成功,共插入 {len(insight_records)} 条记录") + + except Exception as e: + logger.error(f"导入失败: {e}") + +# 导入ReadingRecord CSV到Django模型 +@logger.catch +def import_reading_record_csv(csv_path): + """将阅读记录CSV导入到Django模型""" + try: + logger.info(f"开始导入 {csv_path} 到ReadingRecord模型") + + # 读取CSV文件并导入数据 + with open(csv_path, 'r', encoding='utf-8') as f: + # 跳过表头 + next(f) + + # 读取CSV数据并创建模型实例 + reader = csv.reader(f) + reading_records = [] + for row in reader: + record_date = row[0] + type_id = int(row[1]) + title = row[2] + source = row[3] + progress = row[4] + note = row[5] + + # 确保type_id存在 + if ReadingType.objects.filter(id=type_id).exists(): + reading_records.append(ReadingRecord( + date=record_date, + type_id=type_id, + title=title, + source=source, + progress=progress, + note=note + )) + else: + logger.warning(f"跳过记录: 类型ID {type_id} 不存在") + + # 批量创建 + ReadingRecord.objects.bulk_create(reading_records) + + logger.info(f"导入成功,共插入 {len(reading_records)} 条记录") + + except Exception as e: + logger.error(f"导入失败: {e}") + +# 主函数 +@logger.catch +def main(): + """主函数""" + logger.info("开始执行CSV生成和导入脚本") + + # 生成CSV文件 + reading_type_csv = generate_reading_type_csv() + insight_record_csv = generate_insight_record_csv() + reading_record_csv = generate_reading_record_csv() + + # 导入CSV到Django模型 + import_reading_type_csv(reading_type_csv) + import_insight_record_csv(insight_record_csv) + import_reading_record_csv(reading_record_csv) + + logger.info("脚本执行完成") + +if __name__ == "__main__": + main() diff --git a/insight_record.csv b/insight_record.csv new file mode 100644 index 0000000..9ca9861 --- /dev/null +++ b/insight_record.csv @@ -0,0 +1,11 @@ +date,content +2025-12-25,包括其中电脑方式来源我的经济.次数我们中国无法.需要密码一直具有专业. +2025-12-30,注册来自原因环境起来公司一个. +2026-01-06,一切情况显示结果.也是单位问题表示电影觉得.一个增加今天增加之后记者语言. +2025-12-31,深圳投资经营分析是否人民.因此首页国际因为一点威望之后. +2025-12-21,世界如何生活空间研究.中心不会文章教育其中网站男人之间.社区记者如此而且都是由于. +2025-12-28,成为发现电脑更新网络.登录需要基本出现技术.感觉中国功能单位因为语言. +2025-12-23,标题准备决定.的话只有如此.拥有那么所有上海手机觉得. +2025-12-24,为什产品孩子.怎么处理研究.语言人民的话研究. +2025-12-29,提高在线环境.一样同时今天需要过程朋友各种.方面经营电影发布不会. +2025-12-22,学生一切网络系列情况继续.详细只要的话今天希望.这些进入评论作者需要. diff --git a/logs/app.log b/logs/app.log index b3e0629..8182ffd 100644 --- a/logs/app.log +++ b/logs/app.log @@ -4,3 +4,25 @@ 2026-01-04 19:10:41.211 | INFO | core.views:index:45 - 用户访问首页 2026-01-04 19:11:02.642 | INFO | core.views:yesterday_records:73 - 用户访问昨日记录页面 2026-01-04 19:15:44.290 | INFO | core.views:yesterday_records:73 - 用户访问昨日记录页面 +2026-01-07 22:54:04.870 | INFO | __main__:generate_reading_type_csv:52 - 生成ReadingType CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv +2026-01-07 22:54:04.872 | INFO | __main__:generate_insight_record_csv:77 - 生成InsightRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv +2026-01-07 22:54:04.873 | INFO | __main__:generate_reading_record_csv:106 - 生成ReadingRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv +2026-01-07 22:54:04.873 | INFO | __main__:import_reading_type_csv:114 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv 到ReadingType模型 +2026-01-07 22:54:04.875 | ERROR | __main__:import_reading_type_csv:138 - 导入失败: no such table: core_readingtype +2026-01-07 22:54:04.875 | INFO | __main__:import_insight_record_csv:145 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv 到InsightRecord模型 +2026-01-07 22:54:04.895 | ERROR | __main__:import_insight_record_csv:166 - 导入失败: no such table: core_insightrecord +2026-01-07 22:54:04.895 | INFO | __main__:import_reading_record_csv:173 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv 到ReadingRecord模型 +2026-01-07 22:54:04.912 | ERROR | __main__:import_reading_record_csv:210 - 导入失败: no such table: core_readingtype +2026-01-07 22:54:04.912 | INFO | __main__:main:228 - 脚本执行完成 +2026-01-07 22:54:27.118 | INFO | __main__:generate_reading_type_csv:52 - 生成ReadingType CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv +2026-01-07 22:54:27.119 | INFO | __main__:generate_insight_record_csv:77 - 生成InsightRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv +2026-01-07 22:54:27.120 | INFO | __main__:generate_reading_record_csv:106 - 生成ReadingRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv +2026-01-07 22:54:27.120 | INFO | __main__:import_reading_type_csv:114 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv 到ReadingType模型 +2026-01-07 22:54:27.123 | INFO | __main__:import_reading_type_csv:118 - 已清空现有ReadingType数据 +2026-01-07 22:54:27.127 | INFO | __main__:import_reading_type_csv:135 - 导入成功,共插入 5 条记录 +2026-01-07 22:54:27.128 | INFO | __main__:import_insight_record_csv:145 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv 到InsightRecord模型 +2026-01-07 22:54:27.149 | INFO | __main__:import_insight_record_csv:163 - 导入成功,共插入 10 条记录 +2026-01-07 22:54:27.149 | INFO | __main__:import_reading_record_csv:173 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv 到ReadingRecord模型 +2026-01-07 22:54:27.170 | INFO | __main__:import_reading_record_csv:207 - 导入成功,共插入 15 条记录 +2026-01-07 22:54:27.171 | INFO | __main__:main:228 - 脚本执行完成 +2026-01-07 23:01:51.374 | INFO | core.views:index:45 - 用户访问首页 diff --git a/reading_record.csv b/reading_record.csv new file mode 100644 index 0000000..e977341 --- /dev/null +++ b/reading_record.csv @@ -0,0 +1,16 @@ +date,type_id,title,source,progress,note +2025-12-23,2,发生很多活动国内.,信诚致远信息有限公司,进行中,通过投资起来不会首页非常. +2025-12-27,2,社区其实音乐其实设计.,新宇龙信息信息有限公司,未开始,标准次数主题进入应用支持不过. +2025-12-13,2,帖子主要都是最后.,商软冠联科技有限公司,已完成,就是在线社会任何一下成为以及.男人看到点击日本相关. +2025-12-23,5,地方由于完成有些.,立信电子信息有限公司,已完成,但是技术一样. +2025-12-19,1,资源显示推荐免费.,九方网络有限公司,未开始,就是一次威望北京看到大小进入. +2025-12-27,4,喜欢很多一些.,趋势传媒有限公司,已完成,正在网络其中能力处理必须.谢谢成为北京最后. +2025-12-09,4,免费电脑手机分析而且.,浦华众城信息有限公司,未开始,论坛通过以后. +2025-12-25,2,使用的人到了类别.,天益信息有限公司,未开始,部分由于质量因此到了最大. +2025-12-12,5,来源一切到了.,凌云科技有限公司,已完成,这样必须包括游戏方法不同内容.分析地区一定公司. +2025-12-19,5,网络合作有些.,新宇龙信息网络有限公司,已完成,为了各种同时.积分相关类型. +2025-12-28,2,应该生产加入记者汽车系列.,维旺明传媒有限公司,已完成,相关的话主题工程世界手机.网站知道不同工程价格所以. +2026-01-05,5,直接生产推荐城市.,万迅电脑科技有限公司,进行中,组织支持市场能力然后最新无法. +2026-01-06,2,位置出来标题谢谢注意还有.,盟新信息有限公司,进行中,以及关于数据他的目前. +2025-12-18,5,制作开发全部有些只有.,信诚致远网络有限公司,未开始,这么人民解决威望她的威望.经验客户无法一种. +2026-01-03,5,看到完全最大的人企业这是.,太极传媒有限公司,已完成,由于希望标准有限中心更新以后.影响国际只要其他经济有关对于. diff --git a/reading_type.csv b/reading_type.csv new file mode 100644 index 0000000..6e6ac5b --- /dev/null +++ b/reading_type.csv @@ -0,0 +1,6 @@ +name +书籍 +文章 +论文 +报告 +其他