Python format格式化拼SQL / SQLAlchemy ORM,不固定条件的查询

最近使用python+vue做一个web系统,碰到一个问题。

之前写代码的人,使用的是sqlalchemy提供的ORM框架来查询。查询时做了限定:前端必须选择所有条件才能查询。这样查询条件是固定了,代码也很好写。但是却给使用上带来了麻烦:比如前端有5个查询条件,有些时候想查询只满足1、2个条件下的内容,那怎么办呢?原来的代码肯定就不满足需求了。

当然,这个需求可以用if...else来写,把查询条件从全部为空、任意1个为空、任意2个为空……全不为空,这样全排列一下。每个条件对应一个固定的查询。如果查询条件少了还好说,多了的话,简直是灾难啊!

所以就想到使用动态拼SQL的方式,先写一个这样的语句:

sql_str = "select * from myTable where 1=1"

之后依次根据查询条件是否为空,进行拼接,就像这样:

    if p_id:
        sql_str = sql_str + " and id = p_id"

但是有个问题啊,p_id是个参数,这样在sql字符串里面直接写p_id会被当做字符串,无法获取到参数。

那么如果我直接写一个可以执行的sql,在python下会这么写:

sql_str = "select * from myTable where 1=1 and id = %s" % p_id

所以,不仅要把sql字符串里面的查询条件拼接上,还要把参数也给带上才行。如何带上?通过搜索,发现python2.6之后其实比较提倡使用format来格式化参数,因此上述语句可以改成这样:

sql_str = "select * from myTable where 1=1 and id = {p_id}".format(p_id)

而且,我们还可以通过字典来设置参数,就像这样:

# 通过字典设置参数
site = {"name": "菜鸟教程", "url": "www.runoob.com"}
print("网站名:{name}, 地址 {url}".format(**site))

因此我有了思路:还是按照之前的方式来拼sql字符串,同时把对应的参数加到参数字典里,不就行了吗!

因此,下面给出连接数据库开始,直到完成查询的代码:

#! -*- coding:utf8 -*-
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine("mysql+pymysql://root:root@localhost:3306/mydatabase?charset=utf8mb4")
Session_class = sessionmaker(bind=engine)  
session = Session_class()  

session.execute('use mydatabase;')

hash = {} #字典参数,初始为空
p_id = 1 
m_id = ''
name = 'my' 
# 上面是三个查询条件,其中两个为空

sql_str = "select * from myTable where 1=1"
if p_id:
    sql_str = sql_str+" and p_id = {p_id}"# id, 查询时要精确匹配
    hash['p_id'] = p_id
if m_id:
    sql_str = sql_str+" and m_id = {m_id}"
    hash['m_id'] = m_id
if name:
    sql_str = sql_str + " and name like '%{name}%'"#名字,需要支持模糊查询
    hash['name'] = name

result = session.execute(sql_str.format(**hash))

for r in result:
    print(r)

当然,我还是不知道如何使用ORM框架,来实现这种效果,所以就只能拼SQL啦,可能并不是最好的方式,但起码实现了想要的功能。

如果你知道如何使用sqlalchemy提供的ORM框架来写的话,欢迎告诉我哦!

PS: 自己找到了如何用框架来写,原理差不多,具体见下文:
Python SQLAlchemy 不确定条件查询
https://www.jianshu.com/p/a33f48387efa

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