我真的想要理解SQLAlchemy,但它的进展缓慢而令人困惑。我有以下查询:
INSERT INTO
user (name, email)
SELECT
:name, :email
WHERE NOT EXISTS (
SELECT * FROM other WHERE other.id > :some_id
)
RETURNING id
我希望通过SQLAlchemy以更加pythonic的方式运行它,而不仅仅是提供原始SQL来执行。
我无法确定哪些功能存在于哪些对象 - filter
,where
,insert
,add
...文档非常详细压倒性的,我迷路了。
我已经生成了user
个生成的对象并等待添加到数据库中 - 这是应该这样做的查询,如果有人可以帮我弄清楚如何构建它。
我希望所有人都在一个查询中,因为存在竞争条件,有时我会得到一个新的other
对象,这会使当前user
个对象无效,所以我没有更长的时间想要添加它们。
答案 0 :(得分:1)
我设法使用SQLAlchemy-Core呈现您的查询。我将提供简单Table
对象和使用declarative_base
的模型的示例。
鉴于这个演示代码:
from sqlalchemy import table, column, Unicode, String, Integer
user = table(
'user',
column('id', Integer),
column('name', Unicode),
column('email', String),
)
other = table(
'other',
column('id', Integer),
column('name', Unicode),
column('email', String),
)
如果您使用ORM,那么您的定义可能如下所示:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, Unicode, String
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column('name', Unicode)
email = Column('email', String)
class Other(Base):
__tablename__ = 'other'
id = Column(Integer, primary_key=True)
name = Column('name', Unicode)
email = Column('email', String)
# Pull out the `Table` objects from the mapped models.
user = User.__table__
other = Other.__table__
鉴于此,您可以像这样呈现查询:
from sqlalchemy import select, literal, exists, text
# Your inputs.
name = 'foo'
email = 'foo@example.com'
other_id = 1
# Compile the query for demonstration purposes
print(
user
.insert()
.from_select(
['name', 'email'],
select(
[literal(name),
literal(email)])
.where(~exists([other.c.id])
.where(other.c.id > other_id))
)
.returning(text('id'))
)
编译查询将为您提供以下SQL字符串:
INSERT INTO "user" (name, email) SELECT :param_1 AS anon_1, :param_2 AS anon_2
WHERE NOT (EXISTS (SELECT other.id
FROM other
WHERE other.id > :id_1)) RETURNING id