首页 > 解决方案 > 在 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 处理本质上是字符串的预先存在的数据。

我不清楚在导入过程中的哪一点我应该修改数据类型以将日期、电话号码、生日等转换为整数。

我将非常感谢任何指导,无论是特定的代码行还是对此背后原理的任何元解释,以便我可以将理解应用于这些和未来的问题。

谢谢!

标签: pythondjangocsv

解决方案


我已经使用 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”打开文件没有帮助,因为它会打开一个仅供写入的文件,这将删除文件的所有内容。


推荐阅读