V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
qazwsxkevin
V2EX  ›  Python

请教个 sqlalchemy 的查询方式,想把参数传递到执行语句上。。。

  •  
  •   qazwsxkevin · 2019-09-27 09:07:56 +08:00 · 3641 次点击
    这是一个创建于 1915 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教个 sqlalchemy 的查询方式,想把参数传递到执行语句上。。。

    写了个函数去解决频发 query 操作:

    #从数据库中检查物品名字,如果有,返回物品 ID
    def queryItemNameStrGetItemID(tblName,ItemName,engine,conn):
        tbl = Table(tblName, metadata,autoload=True,autoload_with=engine)#映射了 tblName 表
    
        s = select([tbl.c.ItemID]).where(tbl.c.ItemName) == ItemName)
    
        res = conn.execute(s) #fetchall 结果只能一次有效
        selectreSult = res.fetchall() #selectreSult 是一个 list
        if len(selectreSult) == 0:#如果没有内容
            return None
        else:
            return (selectreSult[0])[0]
    

    在程序上实现:

    main:
    
    ResultDF = pd.DataFrame(************)
    
    engine = create_engine('mysql+pymysql://root:[email protected]:3306/test?charset=utf8')
    queryconn = engine.connect()
    
    
    for i in ResultDF.itertuples():#对 A 列的物品进行历遍
        tmpDFItemNameStr =i[ResultDF.columns.get_loc("A 列") + 1]#从 df 中获取 A 队物品名
        tmpID = queryTeamNameStrgetTeamID('iteam_nick',tmpDFItemNameStr ,engine,queryconn)#找 ID
        if tmpID:
            todoSomethingFunc(tmpID)
            print(tmpID,':',tmpDFItemNameStr)
    
    queryconn.close()
    

    问题是在函数里这句:

    s = select([tbl.c.ItemID]).where(tbl.c.ItemName) == ItemName)
    

    我想用把函数的参数作为表的字段名传入到这一句,是否可以做到?应该如何写?
    select 这个语句的.c.后面的语句,似乎不可以 str 拼接方式完成...

    s = select([tbl.c.AnyID]).where(tbl.c.AnyName) == ItemName)

    如:

    def queryItemNameStrGetItemID(tblName,ItemName,AnyID,AnyName,engine,conn):
    

    这样传入?

    9 条回复    2019-09-27 17:00:09 +08:00
    jiezhi
        1
    jiezhi  
       2019-09-27 09:11:10 +08:00 via iPhone
    改成 tbl.c[AnyID]这样的呢
    Latin
        2
    Latin  
       2019-09-27 09:28:02 +08:00
    提供下我目前做多条件的封装思路
    查询条件列为字典
    filter_dict = {
    "a":tb.cv.ItemName
    }

    根据列取值
    filter_list = [filter_dict.get("a") if a else None ]
    term = [element for element in term if element is not None]
    传递参数
    s = select([tbl.c.ItemID]).where(*term) == ItemName)
    然后欧了
    好像有点词不达意....
    仅供参考
    qazwsxkevin
        3
    qazwsxkevin  
    OP
       2019-09-27 10:18:30 +08:00
    @jiezhi,改成[],在函数部分能编译通过,但是在调用函数部分,字段名不知道应该如何才是正确传入?
    以下方式均不能传入:
    tmpID = AnalyFunc.queryTeamNameStrgetTeamID('iteam_nick',ItemID,ItemName,tmpDFItemNameStr ,engine,queryconn)
    tmpID = AnalyFunc.queryTeamNameStrgetTeamID('iteam_nick','ItemID','ItemName',tmpDFItemNameStr ,engine,queryconn)
    tmpID = AnalyFunc.queryTeamNameStrgetTeamID('iteam_nick',[ItemID],[ItemName],tmpDFItemNameStr ,engine,queryconn)
    tmpID = AnalyFunc.queryTeamNameStrgetTeamID('iteam_nick',*ItemID,*ItemName,tmpDFItemNameStr ,engine,queryconn)

    @Latin,抱歉,真的看不懂,似乎也不适合我这种传入方式?
    lolizeppelin
        4
    lolizeppelin  
       2019-09-27 10:43:50 +08:00
    你这简直不是再用 orm
    和直接撸 sql 有啥区别啊 233
    qazwsxkevin
        5
    qazwsxkevin  
    OP
       2019-09-27 11:55:27 +08:00
    @lolizeppelin 嗯嗯,是的,因为现在表名,表结构,表的字段会经常变化,用 ORM 的方式要做 class 预定义字段的类型,这个不好搞,如果是直撸,代码会简单很多,目前不用 ORM,至少能完成功能先(改 ORM 等表稳定了再改也容易),所以你说得很对,2333 无法避免。。。
    先看看目前这个坑怎么绕? ^_^
    weyou
        6
    weyou  
       2019-09-27 14:53:07 +08:00 via Android
    @qazwsxkevin 表稳不稳定和用不用 orm 没啥直接关系吧
    qazwsxkevin
        7
    qazwsxkevin  
    OP
       2019-09-27 16:50:18 +08:00
    @weyou 用 ORM 的话,不是要做一个 class 类定义了表结构先吗?! 表的字段类型 float,int 不对读写会有问题,也许我对 ORM 理解还不够深入吧。。。。
    suzaku
        8
    suzaku  
       2019-09-27 16:58:35 +08:00
    粗略的看了一下,你是希望传入动态字段?

    field = getattr(tbl.c, AnyName)
    s = select([tbl.c.AnyID]).where(field) == ItemName)

    这样?
    suzaku
        9
    suzaku  
       2019-09-27 17:00:09 +08:00
    更正:
    s = select([tbl.c.AnyID]).where(field == ItemName)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3740 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:52 · PVG 08:52 · LAX 16:52 · JFK 19:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.