You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生产环境(Heroku/PostgreSQL)出现timedelta NoneType TypeError本地无此问题

问题:Heroku+PostgreSQL环境抛出TypeError,本地SQL无异常

在Heroku+PostgreSQL生产环境中遇到错误:TypeError: unsupported type for timedelta hours component: NoneType,但本地SQLite测试环境未出现该问题。

相关代码

模型定义

class ModelC(models.Model):
    model_c_field_1 = models.ForeignKey(Venue, null = True, blank= True, on_delete=models.CASCADE)


class ModelB(models.Model):
    model_c_field_2 = models.ForeignKey(ModelA, blank=True, null=True, on_delete=models.CASCADE)
    model_c_field_1= models.ForeignKey(Venue, blank=True, null=True, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)

业务函数

def function(request, userprofile_id):
    
    latest_model_object = ModelB.objects.filter(user=userprofile_id).order_by('-id')[:1]
 
    time_delta = ()
    for ModelB in latest_model_object:
        
         time_delta = timezone.now() - modelb.created_at
    
    time_delta_rule = ModelC.objects.filter(venue=request.user.userprofile.venue)
    
    timedelta_test=timedelta()
    for ModelC in time_delta_rule:
        
            timedelta_test = timedelta(hours = ModelC.timeframe)
            print(timedelta_test)

错误日志

2023-04-14T04:26:40.379344+00:00 app[web.1]: timedelta_test = timedelta(hours = modelc.timeframe)
2023-04-14T04:26:40.379344+00:00 app[web.1]: TypeError: unsupported type for timedelta hours component: NoneType

原因分析与解决方案

核心原因

错误直接指向ModelC.timeframe的值为None,而timedelta(hours=...)不接受None作为参数。本地与生产环境表现差异的原因:

  1. 生产环境中存在ModelC实例的timeframe字段未赋值(为NULL),但本地测试数据中该字段均为有效值;
  2. SQLite对NULL的处理逻辑更宽松,或本地测试未覆盖timeframe为空的场景。

另外代码存在变量名冲突问题:循环变量名ModelC与模型名重复,易引发混淆,建议改为小写变量名。

具体解决步骤

1. 修复字段定义(可选但推荐)

如果业务逻辑要求timeframe不能为空,修改ModelC的字段定义(当前代码漏写timeframe字段,需补充并禁用空值):

class ModelC(models.Model):
    model_c_field_1 = models.ForeignKey(Venue, null=True, blank=True, on_delete=models.CASCADE)
    timeframe = models.IntegerField()  # 根据实际类型调整,移除null/blank参数确保字段非空

若业务允许timeframe为空,则必须在代码中处理None值。

2. 代码层面处理空值

在创建timedelta前判断timeframe是否为None,避免报错:

timedelta_test=timedelta()
for model_c in time_delta_rule:  # 修改变量名避免与模型名冲突
    if model_c.timeframe is not None:
        timedelta_test = timedelta(hours=model_c.timeframe)
        print(timedelta_test)
    else:
        # 按业务需求处理空值,例如设为默认0小时或跳过
        timedelta_test = timedelta(hours=0)
        print("timeframe为空,使用默认0小时")

3. 清理生产环境数据

登录Heroku的PostgreSQL数据库,查询并处理timeframe为空的记录:

-- 查询空值记录
SELECT * FROM your_app_modelc WHERE timeframe IS NULL;

-- 补全空值(示例:设为0)
UPDATE your_app_modelc SET timeframe = 0 WHERE timeframe IS NULL;

根据业务逻辑,也可直接删除无效记录。

4. 修正代码中的变量名错误

原函数中循环变量名与实例引用不匹配,修正后避免潜在问题:

time_delta = None  # 初始值设为None更合理,原代码的元组类型不适合存储时间差
for model_b in latest_model_object:
    time_delta = timezone.now() - model_b.created_at

内容的提问来源于stack exchange,提问作者PhilM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:03:16