You need to enable JavaScript to run this app. Django ORM查询外部数据库hotel_reviews表时报未知列id错误
优惠活动
大模型
产品
解决方案
定价
更多

Django ORM查询外部数据库hotel_reviews表时报未知列id错误

问题根源

Django ORM 有强制规则:每个模型必须存在一个主键字段。如果模型没有显式标记任何字段为primary_key=True,Django会自动生成一个隐式的id自增主键,对应数据库表的id列。

你的HotelInfo表能正常查询,是因为显式指定了hotel_id为主键,Django不会额外生成id字段;而HotelReviews模型没有任何字段标记为主键,触发了自动生成id的逻辑,查询时就会去拉取数据库里不存在的hotel_reviews.id列,抛出1054错误。

另外你的HotelReviews模型还有笔误:重复定义了两次tag_n4字段,会导致字段映射错误,需要删掉重复行。

解决方案

先确认hotel_reviews表的现有唯一非空字段,根据实际结构选择对应修改:

情况1:表中UUID列本身就是唯一非空的主键

直接给uuid字段加primary_key=True,移除多余的blank=True, null=True(主键本身要求非空唯一),同时删掉重复的tag_n4行,修改后的模型示例:

class HotelReviews(models.Model):
    uuid = models.CharField(db_column='UUID', primary_key=True, max_length=36)
    hotel_id = models.CharField(max_length=32, blank=True, null=True)
    review_title = models.TextField(blank=True, null=True)
    review_url = models.TextField(blank=True, null=True)
    review_score = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    review_date = models.DateField(blank=True, null=True)
    reviewer_name = models.TextField(blank=True, null=True)
    hash_reviewer_name = models.CharField(max_length=200, blank=True, null=True)
    reviewer_location = models.CharField(max_length=100, blank=True, null=True)
    posting_conts = models.IntegerField(blank=True, null=True)
    positive_content = models.TextField(blank=True, null=True)
    negative_content = models.TextField(blank=True, null=True)
    tag_n1 = models.TextField(blank=True, null=True)
    tag_n2 = models.TextField(blank=True, null=True)
    tag_n3 = models.TextField(blank=True, null=True)
    tag_n4 = models.TextField(blank=True, null=True)
    tag_n5 = models.TextField(blank=True, null=True)
    staydate = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'hotel_reviews'
        verbose_name_plural = "Reviews"

情况2:表中没有单列唯一主键,需要用联合字段做主键

如果是多字段联合唯一(比如uuid + hotel_id + review_date的组合唯一),Django 5.0及以上版本支持原生复合主键,可在Meta类中定义:

from django.db.models import CompositeKey

class HotelReviews(models.Model):
    # 其余字段和上面一致,不需要单独设置单个主键
    class Meta:
        managed = False
        db_table = 'hotel_reviews'
        verbose_name_plural = "Reviews"
        # 替换成你实际的联合唯一字段组合
        primary_key = CompositeKey('uuid', 'hotel_id', 'review_date')

如果是Django 5.0以下的旧版本,不支持原生复合主键,可选择一个尽量唯一的字段(比如uuid,即使数据库层面没设为主键,只要值唯一),显式标记为primary_key=True即可避免Django自动生成id字段。

注意事项
  • 因为你的模型设置了managed = False,Django不会修改数据库表结构,所有修改仅适配现有表结构,不会对原有数据库造成影响。
  • 修改完成后重启Django服务再测试查询即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 22:36:03