SQLAlchemy:带多个where条件的SQL表达式

28 投票
4 回答
36662 浏览
提问于 2025-04-17 12:06

我在用SQLAlchemy Core写一个本该很简单的SQL更新语句时遇到了困难。不过,我找不到任何文档、示例或教程来说明如何组合多个条件。我相信这些资料是存在的,只是我找不到。

这是表格:

self.struct    = Table('struct',
                     metadata,
                     Column('schema_name',         String(40),  nullable=False,
                                                                primary_key=True),
                     Column('struct_name',         String(40),  nullable=False,
                                                                primary_key=True),
                     Column('field_type',          String(10),  nullable=True),
                     Column('field_len',           Integer,     nullable=True) )

这是插入和更新的语句:

def struct_put(self, **kv):
   try:
       i = self.struct.insert()
       result = i.execute(**kv)
   except exc.IntegrityError:   # row already exists - update it:
       u = self.struct.update().\
           where((self.struct.c.struct_name==kv['struct_name']
                  and self.struct.c.schema_name==kv['schema_name'])).\
           values(field_len=kv['field_len'],
                  field_type=kv['field_type'])
       result = u.execute()

这段代码插入数据没问题,但更新时却把表里的所有行都更新了。你能帮我理解这个条件语句的语法吗?任何建议都很欢迎,提前谢谢你。

编辑:修正后的条件语句看起来是这样的:

        where((and_(self.struct.c.parent_struct_name==kv['parent_struct_name'],
                    self.struct.c.struct_name==kv['struct_name'],
                    self.struct.c.schema_name==kv['schema_name']))).\

这语法其实很简单,但由于SQLAlchemy有很多层次,搞清楚在这个上下文中到底适用什么,真的挺困难的。

4 个回答

1

在SQLAlchemy中,tablename.c是一个特殊的值,用来构建条件,这些条件在运行时会被SQLAlchemy处理。

在这个具体的例子中,你只是想表达“更新所有行,其中名为struct_name的列与传入的值struct_put(struct_name="struct_value", schema_name="schema_value")匹配,而名为schema_name的列与传入的schema_name值匹配。”

17

你还可以使用 & 这个 python 运算符

比如说:

query.where(
   (ModelName.c.column_name == "column_value") &
   (ModelName.c.column_name == "column_value)
)

假设你有这样的查询:

user_query = User.select().where(
   (User.c.id == 12) &
   (User.c.email == "myemail@gmail.com")
)

这将生成一个原始的 SQL 语句,像这样:

select * from users where id = 12 and email = "myemail@gmail.com"
30

看起来你在用Python的“and”操作符,这个操作符只会判断它周围的一个条件。你应该试试用SQLAlchemy里的“and_”函数。把这两个条件放到“and_”函数里面。

撰写回答