Django:子查询的注释

2024-02-08

我正在尝试注释一个查询集Stationid最近邻的Station使用 Django 2.0.3 和 PostGIS (GeoDjango) 功能。

简化版Station model:

class Station(models.Model):
    name = models.CharField(max_length=128)
    location = models.PointField()
    objects = StationQuerySet.as_manager()

我遇到的问题是尝试计算最近距离,这涉及注释一个引用子查询location在外部查询集中。

from django.db.models import OuterRef, Subquery
from django.contrib.gis.db.models.functions import Distance

class StationQuerySet(models.QuerySet):

    def add_nearest_neighbour(self):
        '''
        Annotates each station with the id and distance of the nearest neighbouring station
        '''
        # Get Station model
        Station = self.model

        # Calculate distances to each station in subquery
        subquery_with_distance = Station.objects.annotate(distance=Distance('location', OuterRef('location')) / 1000)

        # Get nearest from subquery
        nearest = subquery_with_distance.order_by('distance').values('id')[0]

        return self.annotate(
            nearest_station_id=Subquery(nearest)
        )

线路distance = Station.objects.annotate(distance=Distance('location', OuterRef('location')) / 1000)结果出现如下错误:

from apps.bikeshare.models import Station
stations = Station.objects.add_nearest_neighbour()

Error:

Traceback (most recent call last):
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2847, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-cb35ea6d5d8b>", line 1, in <module>
    stations = Station.objects.add_nearest_neighbour()
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/gbrown/Development/transit_bikeshare/apps/bikeshare/querysets.py", line 162, in add_nearest_neighbour
    subquery_with_distance = Station.objects.annotate(distance=Distance('location', OuterRef('location')) / 1000)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/query.py", line 997, in annotate
    clone.query.add_annotation(annotation, alias, is_summary=False)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/sql/query.py", line 975, in add_annotation
    summarize=is_summary)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/expressions.py", line 452, in resolve_expression
    c.lhs = c.lhs.resolve_expression(query, allow_joins, reuse, summarize, for_save)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/contrib/gis/db/models/functions.py", line 58, in resolve_expression
    source_fields = res.get_source_fields()
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/expressions.py", line 349, in get_source_fields
    return [e._output_field_or_none for e in self.get_source_expressions()]
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/expressions.py", line 349, in <listcomp>
    return [e._output_field_or_none for e in self.get_source_expressions()]
AttributeError: 'ResolvedOuterRef' object has no attribute '_output_field_or_none'

想出了一个解决办法,使用原始查询来查找最近的车站并从子查询中选择 id 和距离,奖金解释如下:

class StationQuerySet(models.QuerySet):

    def nearest_neighbour(self):
        '''
        Creates a RawQuerySet of each station with the id and distance of the nearest neighbouring station
        '''
        # Have to execute the query in order to get the list of ids to inject
        ids = tuple(self.values('id').values_list('id', flat=True))

        return self.raw('''
               SELECT
                 A0.id   as id,
                 SUB.closest_id,
                 SUB.closest_distance
               FROM "bikeshare_station" A0
                 CROSS JOIN LATERAL (
                            SELECT
                              B0.id   as closest_id,
                              st_distance_sphere(A0.location, B0.location) as closest_distance
                            FROM "bikeshare_station" B0
                            WHERE A0.id != B0.id
                            ORDER BY A0.location <-> B0.location
                            limit 1
                            ) SUB
               WHERE A0.id IN %s;
           ''', [ids])

Usage

您可以将查询集调用链接在一起以在查找最近邻居之前过滤查询集:

query = Station.objects.filter(name='Albert Gate, Hyde Park')
closest_stations = query.nearest_neighbour()
station = closest_stations[0]
station.name
[out]: 'Albert Gate, Hyde Park'
station.closest_distance
[out]: 133.52459069
station.closest_id
[out]: 6369

SQL解释

这种类型的子查询称为相关子查询,因为它引用外部查询中的列。另外,我需要选择最近车站的多条信息(id, distance, etc.).

子查询被放置在FROM子句,允许选择多列。 ALATERAL需要 join 来允许子查询引用同级表FROM列表。当子查询返回单行时,CROSS可以应用联接来形成基于笛卡尔积而不是共享列的联接表。

子查询使用PostGIS<->运算符,根据车站之间的距离对桌子进行排序的效率要高得多,并且st_distance_sphere,进行点之间的精确距离计算。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django:子查询的注释 的相关文章

随机推荐

  • 使用指向本地 p2 存储库的 tycho 构建本地 eclipse 插件

    我正在创建一些需要第三方插件和功能的 Eclipse 插件和功能 为了将这些依赖项包含到我的项目中 我创建了一个 p2 布局存储库 注意 我的 p2 工件不是 Maven 项目 但是 我正在使用 Maven 风格构建 这是 p2 存储库的
  • 如何在 Nuxt 中设置 SASS/SCSS/sass-loader

    我有一个 Nuxt 应用程序 我想使用 CSS 预处理器 我安装了sass loader纤维依赖性 但安装后 应用程序控制台中会出现一条消息 我在图像和代码中显示了该消息 这是代码错误 WARN email protected cdn cg
  • 双线性插值 - DirectX 与 GDI+

    我有一个 C 应用程序 我为其编写了 GDI 代码 该代码使用 Bitmap TextureBrush 渲染来呈现 2D 图像 可以应用各种图像处理函数 该代码是应用程序中模仿现有 DX9 代码的新路径 它们共享一个公共库来执行所有向量和矩
  • 开源 SharePoint? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有 SharePoint 的开源替代品吗 我想要提供与 SharePoint 相同的层次结构和基于 p
  • 为类创建通用委托

    假设我有非常简单的课程 class Box
  • 在php中格式化电子邮件?

    to email subject Thank You message p Thanks for applying p from email protected cdn cgi l email protection headers From
  • 尽管设置为超过两分钟,但套接字在两分钟后超时

    下列的这个帖子 https stackoverflow com questions 12406628 java socket read time out exception 我有同样的问题 我设法通过一个简单的测试来重现它 我希望你能帮助我
  • 导入错误:无法导入名称“阶乘”

    我想使用 logit 模型并尝试导入 statsmodels 库 我的版本 Python 3 6 8 我得到的最好建议是降级 scipy 但不清楚如何降级以及应该降级到什么版本 请帮忙如何解决 https github com statsm
  • 在iOS 5中,如何使用AudioSession来确保插入耳机时通过扬声器播放音频?

    void viewDidLoad super viewDidLoad NSString filePath NSBundle mainBundle pathForResource 1 ofType mp3 Convert the file p
  • Genymotion不会停止优化应用程序

    我尝试将 Genymotion 与 Android Studio 结合使用 以便可以测试应用程序 但每当我尝试启动模拟器时 它都会显示 Android 正在启动 正在优化应用程序 of 74 并且它会优化一段时间 最终它停止优化 但随后它只
  • 在 eclipse 中为项目生成 Ant 构建文件

    我有一个使用 eclipse 用 Ja va 编写的项目 我想为其生成一个 Ant 构建文件 如何做呢 我经常需要使其与源代码保持同步 以便在修改项目结构时可以将其与代码一起提升到公共存储库 我很抱歉问这样一个愚蠢的问题 我浏览了各个论坛
  • JS:如何处理从 API url 返回的 400 Bad Request 错误

    仍然很缺乏经验 我正在尝试错误处理 400 Bad Request 我有一个带有搜索栏的网站 然后 输入到搜索栏中的值将被放入返回对象的 api url 中 每当输入拼写错误的搜索值时 站点的控制台都会针对 api url 返回 400 错
  • 在 C 中使用变量文件名读取多个具有相似名称的文件?

    我有多个名为sensor0 txt sensor1 txt sensor2 txt 等的文件 我需要打开这些文件 用它们进行计算 并将它们打印在屏幕上 所以我想到了类似的事情 for i 0 i lt N Number of files i
  • 通过JTAG恢复STM32 MCU磨掉的标记

    我有一块可能带有 STM32 MCU 的板 我想为该板制作定制固件 因为库存板有很多问题 不幸的是 电路板制造商很友善地磨掉了所有标记 有没有办法通过 jtag 获取设备 系列 ID 并将其交叉引用到型号 我能找到的一切都是关于获取芯片的唯
  • 非常大的非线性最小二乘优化的收敛

    我正在尝试解决以下问题 我有很多 80000 正在生长的器官表面斑块 我随着时间的推移 18 个时间点 测量它的每个面积 并希望拟合一条增长曲线 双逻辑模型 例如 只是两个逻辑函数 bcs 的总和 在观察期 我有框约束来确保指数项不会爆炸
  • 如何在 MongoDB 中执行 SQL Join 等效操作?

    如何在 MongoDB 中执行 SQL Join 等效操作 例如 假设您有两个集合 用户和评论 我想提取 pid 444 的所有评论以及每个集合的用户信息 comments uid 12345 pid 444 comment blah ui
  • 使用 Google Play 提供的上传密钥签署 APK

    我正在尝试了解如何在使用 Google Play 应用签名时将应用上传到 Google Play 这是我所做的 创建了一个应用程序 使用 keytool exe 为该应用程序生成密钥 已将应用上传至 Google Play 已注册 Goog
  • 在图的顶层绘制圆圈

    我正在制作一个图形 试图在组合颜色图和等高线图的顶部绘制一个圆圈 圆圈不断地绘制在轮廓下方而不是轮廓上方 参见下图 我尝试重新排序如何调用 imshow contour 和 Circle 看看是否能让圆圈显示在顶部 但我没有任何运气 有没有
  • .NET 3.5 是媒体中心插件的合理先决条件吗?

    我们有一个开源媒体中心插件 目前它的下载大小只有区区一兆字节 如果我将插件更改为需要 NET 3 5 用户可能需要下载197 megs http www west wind com weblog posts 292203 aspx只是为了能
  • Django:子查询的注释

    我正在尝试注释一个查询集Station与id最近邻的Station使用 Django 2 0 3 和 PostGIS GeoDjango 功能 简化版Station model class Station models Model name