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

2019-09-27 09:07:56 +08:00
 qazwsxkevin

请教个 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:root123@192.168.89.66: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):

这样传入?

3507 次点击
所在节点    Python
9 条回复
jiezhi
2019-09-27 09:11:10 +08:00
改成 tbl.c[AnyID]这样的呢
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
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
2019-09-27 10:43:50 +08:00
你这简直不是再用 orm
和直接撸 sql 有啥区别啊 233
qazwsxkevin
2019-09-27 11:55:27 +08:00
@lolizeppelin 嗯嗯,是的,因为现在表名,表结构,表的字段会经常变化,用 ORM 的方式要做 class 预定义字段的类型,这个不好搞,如果是直撸,代码会简单很多,目前不用 ORM,至少能完成功能先(改 ORM 等表稳定了再改也容易),所以你说得很对,2333 无法避免。。。
先看看目前这个坑怎么绕? ^_^
weyou
2019-09-27 14:53:07 +08:00
@qazwsxkevin 表稳不稳定和用不用 orm 没啥直接关系吧
qazwsxkevin
2019-09-27 16:50:18 +08:00
@weyou 用 ORM 的话,不是要做一个 class 类定义了表结构先吗?! 表的字段类型 float,int 不对读写会有问题,也许我对 ORM 理解还不够深入吧。。。。
suzaku
2019-09-27 16:58:35 +08:00
粗略的看了一下,你是希望传入动态字段?

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

这样?
suzaku
2019-09-27 17:00:09 +08:00
更正:
s = select([tbl.c.AnyID]).where(field == ItemName)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/604648

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX