django通过orm外键关联查询,导出原生sql执行,mysql两表中重复字段被覆盖问题

如何实现mysql语句效果 : “SELECT field as x…” with Django ORM 参考地址

场景描述

最近因业务需求,这边需要做一个数据导出,需要用到两张表的数据来满足,A表和B表,属于一对多的数据关系,因此首先想到的就是django orm 的外键关联查询,借助django-restfuldjango-filter的强大组合,轻松实现这个组合查询。数据量的问题,考虑到耗时,采用celery来异步完成数据处理,所以就借助django orm的功能,获取映射的原生sql,将sql传入tasks任务中,让数据库执行和导出放在task下来处理。

一切按照计划进行,期间还是遇到一些问题。

class B(models.Model):
    id = models.AutoField(db_column='f_id', primary_key=True)
    email = models.CharField(db_column='f_email', max_length=32, default='', help_text=u'邮箱')
    address = models.CharField(db_column='f_address', max_length=32, default='', help_text=u'地址')

class A(models.Model):
    id = models.AutoField(db_column='f_id', primary_key=True)
    name = models.CharField(db_column='f_name', max_length=32, default='', help_text=u'姓名')
    b= models.ForeignKey(B, db_column='f_email', to_field='email', db_constraint=False, help_text=u'邮箱')
from django_filters import rest_framework as filters
class AListFilter(filters.FilterSet):
    """请款记录"""
    address = filters.CharFilter(name='b__address')

    class Meta:
        model = A
        fields = ('address',)

问题:

A与B两表在orm中未使用外键关系ForeignKey标记

虽然在数据库中有关联两表的唯一字段,但是并不是一个无意义的唯一id值,而是我们的业务单号,若添加外键,影响到原表的该字段存储方式。这里采用了继承,将业务单号字段单独抽取,其余的公共字段置为一个抽象model下,这样,采用继承,一个子类保持原名称和业务号字段不变,另一个采用ForeignKey。外键关联的字段需要是唯一的,默认指定为关联model的主键id,这里通过to_field指定为需要关联的唯一字段。这样就可以使用orm的关联查询,通过select_related来正向关联查询。

django-filter 如何接受关联表的参数筛选

在我们定义的AListFilter中,address字段的指定查询为b__address,即可自动关联执行查询。

获取orm映射sql

原因为简单的通过A.objects.all().query就可以获取到sql语句,这里其实拿到的是一个Query对象,需要通过str()获取其sql字符串,一切都是很顺利,但是在运行时,查询报错了,原来是这样拼接出来的sql对于传参的占位符%s未使用引号包裹,导致报错参数类型不是整形。通过对Query类查询,发现__str__魔法方法是将sql和变量拼接得到的,sql, params = A.objects.all().query.sql_with_params()其中的sql占位符确实没有引号,MySQL-python的执行函数,支持对占位sql和参数传入,会自动处理这个%s占位符的问题。

映射sql中两表字段名一样的字段,在执行结束后获取的值被后面的覆盖

对于A和B中的字段名一样问题,django的聚合函数annotate可以实现将sql指定别名,A.objects.all().annotate(other_name=F('name')),这样,就可以避免字段名一样被覆盖的问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 3,802评论 0 8
  • Django 1.8.2 文档Home | Table of contents | Index | Modules...
    轩辕小爱阅读 2,343评论 0 2
  • Web框架之Django: (1)简介: Django是一个由Python写成开源的重量级Web应用框架,采用MT...
    老肖阅读 3,042评论 0 18
  • Django 准备 “虚拟环境为什么需要虚拟环境:到目前位置,我们所有的第三方包安装都是直接通过 pip inst...
    33jubi阅读 1,313评论 0 5
  • 灵感往往来自一瞬间,于是靠着这种感觉改变一下自己,做一个新的尝试,对自己的行为做一个调整。比如学习这件事,有那么一...
    乐L阅读 246评论 0 1