首页 > 解决方案 > 如何为数据库模型手动创建正确的主键

问题描述

我的问题有点类似于这里讨论的问题: Django automatically create primary keys for existing database tables

但不是简单,而是python manage.py inspectdb我做了python manage.py inspectdb --include-views。我的问题是那些基于视图的类——我明白了Error 1054, ("Unknown column 'station_measurements_with_data.id' in 'field list'")

我试图简单地添加id = models.IntegerField(primary_key=True)到模型中,但没有任何乐趣。

模型类如下所示:

class StationMeasurementsWithData(models.Model):
    station_id = models.IntegerField()
    measurement_id = models.IntegerField()
    time_utc = models.DateTimeField()
    pollution_name = models.CharField(max_length=45)
    measurement_value = models.FloatField(blank=True, null=True)

    class Meta:
        managed = False  # Created from a view. Don't remove.
        db_table = 'station_measurements_with_data'

数据库中的视图数据如下所示:

# station_id, measurement_id, time_utc, pollution_name, measurement_value
955, 87318, 2012-01-01 02:00:00, pm2.5, 73
955, 87318, 2012-01-01 02:00:00, pm10, 308
956, 87319, 2012-01-01 02:00:00, pm2.5, 123
956, 87319, 2012-01-01 02:00:00, pm10, 152
957, 87320, 2012-01-01 02:00:00, pm2.5, 163
957, 87320, 2012-01-01 02:00:00, pm10, 198

如果任何列包含唯一值,我只会将其设为主键,但没有。在这种情况下我该怎么办?

标签: pythonmysqldjango

解决方案


inspectdbmanagement 命令仅生成反映其运行的数据库中的表和视图的模型。

如果您不声明它,则将自动主键字段添加到模型中。为避免以后的代码读者混淆,建议在使用非托管模型时指定您正在建模的数据库表中的所有列。
参考https ://docs.djangoproject.com/en/2.2/ref/models/options/#managed

我建议重新创建包含id字段的视图。

如果您的数据库服务器是或为您的特定数据库服务器找到另一种方式,您可以ROW_NUMBER在结果集上使用窗口函数模拟自动递增的 id 。例如postgresql

CREATE VIEW v_foo AS
SELECT ROW_NUMBER() OVER () AS id, [[rest fields]]  FROM foo;

推荐阅读