Python 正在执行sqlalchemy查询

Python 正在执行sqlalchemy查询,python,sqlalchemy,exists,Python,Sqlalchemy,Exists,我很难理解如何执行查询来检查和查看sqlalchemy中是否已经存在匹配的记录。我在网上找到的大多数示例似乎都引用了我没有的会话和查询对象 下面是一个简短的完整程序,说明了我的问题: 1.使用person表在内存中设置sqlite db。 2.在person表中插入两条记录。 3.检查表中是否存在特定记录。这就是它呕吐的地方 from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData from sq

我很难理解如何执行查询来检查和查看sqlalchemy中是否已经存在匹配的记录。我在网上找到的大多数示例似乎都引用了我没有的会话和查询对象

下面是一个简短的完整程序,说明了我的问题: 1.使用person表在内存中设置sqlite db。 2.在person表中插入两条记录。 3.检查表中是否存在特定记录。这就是它呕吐的地方

from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData
from sqlalchemy.sql.expression import exists

engine = create_engine('sqlite:///:memory:', echo=False)
metadata = MetaData()

person = Table('person', metadata,
                        Column('id', Integer, primary_key=True),
                        Column('name', String(255), nullable=False))

metadata.create_all(engine)
conn = engine.connect()

s = person.insert()
conn.execute(s, name="Alice")
conn.execute(s, name="Bob")

print("I can see the names in the table:")
s = person.select()
result = conn.execute(s)
print(result.fetchall())

print('This query looks like it should check to see if a matching record exists:')
s = person.select().where(person.c.name == "Bob")
s = exists(s)
print(s)

print("But it doesn't run...")
result = conn.execute(s)
该程序的输出为:

I can see the names in the table:
[(1, 'Alice'), (2, 'Bob')]
This query looks like it should check to see if a matching record exists:
EXISTS (SELECT person.id, person.name 
FROM person 
WHERE person.name = :name_1)
But it doesn't run...
Traceback (most recent call last):
  File "/project_path/db_test/db_test_env/exists_example.py", line 30, in <module>
    result = conn.execute(s)
  File "/project_path/db_test/db_test_env/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 945, in execute
    return meth(self, multiparams, params)
  File "/project_path/db_test/db_test_env/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 265, in _execute_on_connection
    raise exc.ObjectNotExecutableError(self)
sqlalchemy.exc.ObjectNotExecutableError: Not an executable object: <sqlalchemy.sql.selectable.Exists object at 0x105797438>
exists用于SQL子查询。如果您有一个包含作者id博客文章的posts表,映射回people,您可以使用如下查询查找发表博客文章的人员:

select * from people where exists (select author_id from posts where author_id = people.id);
不能将exists作为SQL查询中最外层的语句;它是SQL布尔子句中使用的运算符。 因此,SQLAlchemy不允许您执行该查询,因为它的格式不正确。
如果要查看行是否存在,只需构造一个带有where子句的select语句,并查看查询返回的行数。

s.exists仅构建exists子句。要使代码正常工作,只需为其生成一个select

s = exists(s).select()
以下是您的完整示例:

from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData
from sqlalchemy.sql.expression import exists

engine = create_engine('sqlite:///:memory:', echo=False)
metadata = MetaData()

person = Table('person', metadata,
                        Column('id', Integer, primary_key=True),
                        Column('name', String(255), nullable=False))

metadata.create_all(engine)
conn = engine.connect()

s = person.insert()
conn.execute(s, name="Alice")
conn.execute(s, name="Bob")

print("I can see the names in the table:")
s = person.select()
result = conn.execute(s)
print(result.fetchall())

print('This query looks like it should check to see if a matching record exists:')
s = person.select().where(person.c.name == "Bob")
s = exists(s).select()
print(s)

print("And it runs fine...")
result = conn.execute(s)
print(result.fetchall())
请尝试以下方法:

...
s = person.select().where(person.c.name == "Bob")
s = select(exists(s))
print(s)
...

除非有人提出更好的答案,以下是我想出的有效答案。让DB对匹配的记录进行计数,并只将计数发送给python应用程序

from sqlalchemy import select, func   # more imports not in my example code above

s = select([func.count(1)]).select_from(person).where(person.c.name == "Bob")
print(s)
record_count = conn.execute(s).scalar()
print("Matching records: ", record_count)
示例输出:

SELECT count(:count_2) AS count_1 
FROM person 
WHERE person.name = :name_1
Matching records:  1

谢谢你,山姆,但我想应该有更好的办法。我不想从数据库中传输可能存在大量匹配行的内容,我只想传输true或false标量值。请在查询中添加限制1。这就是我看到的很多网络应用程序所做的。谢谢!这正是我想要的!我离得太近了,我就是想不出怎么把多余的选择包起来。非常感谢。我可能只做了一个小改动:result=conn.executes.scalar,所以我们只返回基本的True/False,而不是结果行。