python - 在 Django models.py 中将 .csv 字符串数据转换为 DateField 类型
问题描述
我在 Debian 10 上使用 Python 3.7
我有许多包含这些列的预先存在的 .csv 文件:first_name、last_name、birthdate、phone、email 我将它们导入到以 Django 作为框架的 postgres 数据库中。
我的 Django 模型:
from django.db import models
class User(models.Model):
first_name = models.TextField(blank=False, null=False)
last_name = models.TextField(blank=False, null=False)
birthdate = models.TextField(blank=True, null=True)
phone = models.TextField(blank=False, null=False)
email = models.TextField(blank=False, null=False)
自定义 Django 管理命令导入文件 import_users.py:
class Command(BaseCommand):
def handle(self, *args, **options):
users_file = open(f'{settings.DATA_IMPORT_LOCATION}/users.csv', 'r')
for counter, line in enumerate(users_file):
line_fields = line.split(',')
first_name = line_fields[0]
last_name = line_fields[1]
birthdate = line_fields[2]
phone = line_fields[3]
email = line_fields[4]
u = User()
u.first_name = first_name
u.last_name = last_name
u.birthdate = birthdate
u.phone = phone
u.email = email
u.save()
运行以下 Django ORM 查询时的输出示例:
> for u in User.objects.all():
print(u.birthdate)
输出:
birthdate
2015-05-28
2009-06-14
2007-01-01
2007-02-17
2008-05-16
2013-01-19
2008-07-24
2015-05-01
2007-06-03
2007-01-17
当birthdate = models.TextField 设置为TextField 时,我可以使用我的管理命令将这些.csv 文件成功导入我的Postgres 数据库。
这是有道理的,因为所有 .csv 数据都是字符串。
但是,我想正确地将模型设置为读取日期,即birthdate = models.DateField() 以便进行进一步的计算,例如在特定时间增量内查找用户的生日
当对 DateField 进行此更改,然后尝试使用命令 ./manage.py import_users 将 .csv 导入数据库时,我收到以下错误:“ ValueError: time data 'birthdate' does not match format '%Y-%m- %d'"
我尝试使用以下命令将 .csv 生日数据转换为 import_users.py 中的日期时间对象:
u.birthdate = datetime.datetime.strptime(birthdate, "%Y-%m-%d")
以及对此的许多变体,但错误消息是相同的。
我想我不明白如何正确修改给定列的数据。我还更改了我的 .csv 导入代码,以使用“w”而不是“r”(users_file = open(f'{settings.DATA_IMPORT_LOCATION}/users.csv', 'w')
)读取,但这无济于事。
当我尝试将models.py 字段更改为TextField 以外的任何内容时,我遇到了这个问题。同样,这在概念上是有道理的,因为我要求 Django 处理本质上是字符串的预先存在的数据。
我不清楚在导入过程中的哪一点我应该修改数据类型以将日期、电话号码、生日等转换为整数。
我将非常感谢任何指导,无论是特定的代码行还是对此背后原理的任何元解释,以便我可以将理解应用于这些和未来的问题。
谢谢!
解决方案
我已经使用 Django 3.2.2 和 Postgres docker 容器对此进行了测试,并且我能够简单地保存日期字符串(例如“2007-02-17”)而无需任何额外的类型转换。检索保存的模型时,Django 将日期字段作为 datetime.date 对象返回。
>>> u.birthdate = "2007-02-17"
>>> u.save()
>>> u = TestModel.objects.last()
>>> u.birthdate
datetime.date(2007, 2, 17)
也许您可以在将其保存到生日之前尝试打印值line_fields[2]
,以检查是否保存了正确的值。
作为旁注,使用“w”打开文件没有帮助,因为它会打开一个仅供写入的文件,这将删除文件的所有内容。
推荐阅读
- php - 时间格式的种类
- java - 有界并发优先级队列
- c# - 从另一个包含的类对象访问包含的类对象中的数据的“OOP 方式”是什么?
- tensorflow - 如何通过改组将张量流数据集拆分为 N 个数据集
- sql - DROP COLUMN 后 Oracle 会损坏其他列的数据
- javascript - D3 散点图新手
- mysql - MySQL Workbench 无法连接到我的 RDS 数据库:无法连接到 localhost
- node.js - nodejs 使用 createCipheriv 恢复 createCipher 数据
- javascript - React-Redux:并非所有调度都出于某种原因工作
- google-play - 无法验证您的 ID Play 商店