首页 > 编程问答 >我可以检查 sqlalchemy 查询对象来查找已连接的表吗?

我可以检查 sqlalchemy 查询对象来查找已连接的表吗?

时间:2024-07-26 15:46:37浏览次数:10  
标签:python join sqlalchemy flask-sqlalchemy

我正在尝试以编程方式构建一个搜索查询,为此,我要加入一个表。

class User(db.Model):
    id = db.Column(db.Integer(), primary_key=True)

class Tag(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
    title = db.Column(db.String(128))
    description = db.Column(db.String(128))

这是一个有点人为的示例 - 我希望它有意义。

假设我的搜索函数看起来像什么像:

def search(title_arg, desc_arg):
    query = User.query
    if title_arg:
        query = query.join(Tag)
        query = query.filter(Tag.title.contains(title_arg))
    if desc_arg:
        query = query.join(Tag)
        query = query.filter(Tag.description.contains(desc_arg))

    return query

以前,我一直跟踪哪些表已经加入到列表中,如果该表在列表中,则假设它已经加入,然后添加过滤器。

这将是如果我可以查看查询对象,看到 Tag 已经加入,如果是的话就跳过它,那太酷了。我有一些更复杂的查询构建,它们确实会从中受益。

如果对于我错过的搜索有一个完全不同的查询构建策略,那也很棒。或者,如果我两次加入表,上面的代码就可以了,那也是很好的信息。任何帮助都非常感谢!


可以通过检查查询的 _from_obj 属性来访问 SQLAlchemy 查询对象中连接的表。此属性包含构成查询 FROM 子句的一系列表。

以下是检查 Tag 表是否已连接到的 search 函数的方法:

from sqlalchemy import inspect

def search(title_arg, desc_arg):
    query = User.query
    if title_arg:
        # 检查 Tag 是否已连接
        if not any(isinstance(table, Tag.__table__) for table in inspect(query).fromclause._from_obj):
            query = query.join(Tag)
        query = query.filter(Tag.title.contains(title_arg))
    if desc_arg:
        # 检查 Tag 是否已连接
        if not any(isinstance(table, Tag.__table__) for table in inspect(query).fromclause._from_obj):
            query = query.join(Tag)
        query = query.filter(Tag.description.contains(desc_arg))

    return query

此代码使用 inspect(query).fromclause._from_obj 获取连接表的列表,并检查 Tag.__table__ 是否存在于列表中。如果该表不存在,则会执行连接。

但是,在 SQLAlchemy 中,多次连接同一个表通常是不必要的,甚至可能导致意外行为。 SQLAlchemy 足够智能,可以处理多个过滤器,即使它们应用于通过单个连接连接的同一表。

因此,可以简化 search 函数,而无需检查表是否已连接:

def search(title_arg, desc_arg):
    query = User.query
    if title_arg:
        query = query.join(Tag).filter(Tag.title.contains(title_arg))
    if desc_arg:
        query = query.join(Tag).filter(Tag.description.contains(desc_arg))
    return query

此代码仅在需要时连接 Tag 表,并且无论 title_arg desc_arg 的值如何,它都能正常工作。SQLAlchemy 将优化查询,并且不会执行不必要的连接。

标签:python,join,sqlalchemy,flask-sqlalchemy
From: 35829083

相关文章

  • python框架之Flask
    之前写过有关flask-restful: https://www.cnblogs.com/xingxia/p/flask_restful.html虽然早期使用python进行web应用搭建的使用该框架,但是好像很少总结,在此记录一下 [安装]pip3installflask [使用]#导入类库fromflaskimportFlask#创建实例......
  • Python 搜索和抓取
    我有一个问题想知道是否值得花时间尝试用Python来解决。我有一个包含鱼类学名的大型CSV文件。我想将该CSV文件与大型鱼类形态信息数据库(www.fishbase.ca)交叉引用,并让代码返回每条鱼的最大长度。基本上,我需要创建代码来搜索Fishbase网站上的每条鱼,然后找到页面上的最......
  • 《最新出炉》系列入门篇-Python+Playwright自动化测试-54- 上传文件(input控件) - 上篇
    1.简介在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等。所以宏哥打算按上传文件的分类对其进行一下讲解和分享。2.上传文件的API(input控件)Playwright是一个现代化的自动化测试工具,它支持多种浏览器和操作系统,可以帮助开发人员和......
  • python requests 报错 Caused by ProxyError ('Unable to connect to proxy', OSError
    背景:访问https接口,使用http代理版本:requests:2.31.0 从报错可以看出,是proxy相关的报错调整代码,设定不使用代理,将http与https对应的proxy值置空即可(尝试过proxies={},但此写法不生效)proxies={'http':'','https':''}response = requests.get('https://xxx......
  • python基础函数
    1.为什么使用函数使用函数的目的是去减少代码的冗余性,简化代码的复杂度2.如何去定义一个函数以def开头去进行相关的定义在def的后面我们就去以见明知意的方式去定义一个函数的名称在函数名称后面的括号中去添加参数值,可以是多个参数,也可以是无餐的3.函数的调用无参多......
  • 不使用 + 或 - 运算符 | 添加 2 个数字Python
    我一直在尝试编写逻辑,但测试用例失败。如何改进我的代码?代码:#Giventwointegersaandb,returnthesumofthetwointegerswithoutusingtheoperators+and-.a=-1b=1min_val=min(a,b)max_val=max(a,b)ifmin_val==max_val:pr......
  • python 中的智能 Cisco IOS 差异
    之前:hostnameFoo!interfaceGigabitEthernet1/1switchportmodetrunkswitchporttrunkallowedvlan10,20,30!interfaceGigabitEthernet1/2ipaddress192.0.2.1255.255.255.128noipproxy-arp!之后:hostnameFoo!interfaceGigabitEt......
  • 无法编译 Arduino ESP32 代码:.../python3: exec 格式错误
    昨天我使用MacOSArduinoIDE或VSCode编译Arduino草图没有任何问题。但今天什么也编译不了。我尝试在ArduinoIDE或带有Arduino扩展的VSCode中编译的任何草图都会出现此错误:fork/exec/Library/Frameworks/Python.framework/Versions/3.11/bin/python3:exec......
  • 用Python解析邮件日志
    我的任务有点困难。我有一个邮件日志,如:Oct315:30:18mail1postfix/lmtp[5369]:DB10242054:to=<XXXXX>,orig_to=<XXXXXX>,relay=ip[ip]:port,delay=1.4,delays=0.04/0/0.01/1.4,dsn=2.0.0,status=sent(2502.0.0fromMTA(smtp:[iP]:port):2502.0.0Ok:queueda......
  • Python,Pyinstaller打包含taichi模块的程序
    Python版本3.9、taichi版本1.7.1,pyinstaller版本6.9.0问题描述:正常Pyinstaller打包后报错[Taichi]version1.7.1,llvm15.0.1,commit0f143b2f,win,python3.9.19[Taichi]Startingonarch=x64Traceback(mostrecentcalllast):File"taichi\lang\_wrap_inspec......