如何将 Django 的 DurationField 与 Postgres 一起使用,当之前使用 sqlite 定义时?



我最近将所有数据从sqlite移动到了postgres。除了duration字段外,所有字段似乎都可以正常工作。它在管理面板中显示为一个整数,不允许我编辑或保存。

它与sqlite配合良好。然而,在转到Postgres后,我收到了以下错误(在保存或更新时(:

/admin/content/movie/add/上的编程错误

列"持续时间";是bigint类型,但表达式是interval 类型

提示:您需要重写或强制转换表达式。

class Movie(models.Model):
"""
Stores movie related information.
"""
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
name = models.CharField(verbose_name='name', max_length=100, blank=False, unique=True)
slug = models.SlugField(verbose_name='slug', null=True, blank=True)
description = models.TextField(verbose_name='description', blank=True)
poster = models.ImageField(verbose_name='poster',upload_to='posters/movies', default='defaults/video.webp', validators=[validate_image])
# Field of interest
duration = models.DurationField(verbose_name='duration')
created_at = models.DateTimeField(verbose_name='created_at', auto_now_add=True)

我还使用了以下length方法成功地将字段转换为人类可读的形式(当使用sqlite时(,但在转到postgres后它就不起作用了。上面写着:

duration(int(没有"days"属性

def length(self):
"""
Converts timedelta into hours and minutes.
"""
days, seconds = self.duration.days, self.duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
if hours == 0:
length = f'{minutes} min'
else:
if minutes == 0:
length = f'{hours} h'
else:
length = f'{hours} h {minutes} min'
return length

注意:我使用pgloader加载sqlite数据。https://pgloader.readthedocs.io/en/latest/quickstart.html#migrating-来自sqlite

从这里开始工期字段:

一个用于存储时间段的字段-在Python中通过timedelta建模。在PostgreSQL上使用时,使用的数据类型是间隔,而在Oracle上,数据类型是interval DAY(9(TO SECOND(6(。否则将使用微秒的bigint。

因此,您需要将模型中的字段设置为IntegerField以匹配数据,或者将数据更改为Postgresinterval。由于在SQLite中,数据存储为微秒,因此类似于:


select (1000000::text || ' microseconds')::interval;
interval 
----------
00:00:01

最新更新