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

问题描述 投票:0回答:4

我在 SQLAlchemy Core 中编写简单的 SQL 更新语句时遇到困难。但是,我找不到任何说明如何组合多个 where 条件的文档、示例或教程。我确信它就在那里 - 只是找不到它。

这是表格:

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 子句的语法吗?欢迎所有建议 - 提前致谢。

编辑:更正后的子句如下所示:

        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 的多层,很难确定在此上下文中到底应用了什么。

python sqlalchemy
4个回答
30
投票

在我看来,您正在使用 Python 的“and”操作,该操作将仅评估其周围的子句之一。您应该尝试使用 SQLAlchemy 中的“and_”函数。将这两个子句放在“and_”函数中。


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 == "[email protected]")
)

这将生成这样的原始 SQL

select * from users where id = 12 and email = "[email protected]"

2
投票

在 SQLAlchemy 中,

tablename.c
是一个特殊值,您在构造将由 SQLAlchemy 在运行时处理的条件时使用。

在这种特殊情况下,您只是说“更新名为

struct_name
的列与传入
struct_put(struct_name="struct_value", schema_name="schema_value")
的值匹配的所有行,并且名为
schema_name
的列与作为
schema_name
传入的值匹配。


0
投票

根据 docs

Select.where()
还接受多个条件作为
*whereclause
,并具有默认的
AND
行为:

stmt = (
    select(Table)
    .where(
        Table.firstname == "John",
        Table.lastname == "Smith"
    )
)
© www.soinside.com 2019 - 2024. All rights reserved.