SQLAlchemy 仅从连接表中选择列
Posted
技术标签:
【中文标题】SQLAlchemy 仅从连接表中选择列【英文标题】:SQL Alchemy select columns from joined tables only 【发布时间】:2022-01-03 17:29:17 【问题描述】:我想以 orm 方式运行一个有效的 sql 原始查询。我需要从加入的表中选择列和列数的地方,而不是来自主的任何列。如何以 ORM 方式实现。
我的原始查询(我通常在 sql server 中使用):
原始 SQL:
SELECT [barcode].[dbo].[Tbl_ProductionMaster].[ProductionName]
,[barcode].[dbo].[Tbl_barcode].[Size]
,COUNT([barcode].[dbo].[Tbl_barcode].[Size])
FROM [barcode].[dbo].[tbl_ProductionScan]
INNER JOIN [barcode].[dbo].[Tbl_barcode] ON [barcode].[dbo].[Tbl_barcode].[Serial_no] = [barcode].[dbo].[tbl_ProductionScan].[serial_no]
INNER JOIN [barcode].[dbo].[Tbl_ProductionMaster] ON [barcode].[dbo].[Tbl_ProductionMaster].[ProductionCode] = [barcode].[dbo].[Tbl_barcode].[Product_code]
WHERE [barcode].[dbo].[tbl_ProductionScan].[prod_date] BETWEEN '2021-08-01 08:00:00' AND '2021-08-25 08:00:00' AND [barcode].[dbo].[Tbl_ProductionMaster].[ProductionName] Like '%3780%black%'
GROUP BY [barcode].[dbo].[Tbl_ProductionMaster].[ProductionName], [barcode].[dbo].[Tbl_barcode].[Size]
我在 SQL Alchemy 中所做的事情:
result = (
session.query(ProductionMaster.article, Barcode.size, sa.func.count(Barcode.size))
.join(Barcode, Barcode.serial_no == ProductionScan.serial_no)
.join(ProductionMaster, ProductionMaster.prod_code == Barcode.prod_code)
.filter(
sa.and_(
ProductionScan.date >= "2021-08-01 08:00:00",
ProductionScan.date <= "2021-08-25 08:00:00",
ProductionMaster.article.like("%3780%black%"),
)
)
.group_by(ProductionMaster.article, Barcode.size)
.all()
由于返回的原始查询不正确,因此运行出错。
错误:
The multi-part identifier "tbl_ProductionScan.serial_no" could not be bound. (4104) (SQLExecDirectW)')
从 sqlalchemy 错误返回的原始 sql:
[SQL: SELECT [Tbl_ProductionMaster].[ProductionName] AS [Tbl_ProductionMaster_ProductionName], [Tbl_barcode].[Size] AS [Tbl_barcode_Size], count([Tbl_barcode].[Size]) AS count_1
FROM [tbl_ProductionScan], [Tbl_ProductionMaster] JOIN [Tbl_barcode] ON [Tbl_barcode].serial_no = [tbl_ProductionScan].serial_no JOIN [Tbl_ProductionMaster] ON [Tbl_ProductionMaster].[ProductionCode] = [Tbl_barcode].[Product_Code]
WHERE [tbl_ProductionScan].prod_date >= ? AND [tbl_ProductionScan].prod_date <= ? AND [Tbl_ProductionMaster].[ProductionName] LIKE ? GROUP BY [Tbl_ProductionMaster].[ProductionName], [Tbl_barcode].[Size]]
在这个 sqlalchemy 查询中,我如何在 FROM
关键字中获得 Tbl_ProductionScan
的乘车体验。我只需要Tbl_ProductionScan
,所有其余的表Tbl_ProductionMaster
,Tbl_Barcode
仅在JOIN
关键字中。这样 sqlalchemy orm 匹配我在顶部给出的实际原始查询。
【问题讨论】:
这也可以通过添加 select_from optionresult = ( session.query(ProductionMaster.article, Barcode.size, sa.func.count(Barcode.size)).select_from(ProductionScan) .join(Barcode, Barcode.serial_no == ProductionScan.serial_no) .join(ProductionMaster, ProductionMaster.prod_code == Barcode.prod_code) .filter( sa.and_( ProductionScan.date >= "2021-08-01 08:00:00", ProductionScan.date <= "2021-08-25 08:00:00", ProductionMaster.article.like("%3780%black%"), ) ) .group_by(ProductionMaster.article, Barcode.size) .all()
【参考方案1】:
我知道过滤,请确保您将字符串转换为日期,并且您是否尝试过滤两个字符串值(使用或)或一个
start_date = datetime.strptime("2021-08-01 08:00:00", "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime("2021-08-25 08:00:00", "%Y-%m-%d %H:%M:%S")
search = "%%%".format("3780", "black")
然后尝试运行它
result = session.query(ProductionScan, ProductionMaster, Barcode, )
.join(Barcode, Barcode.serial_no == ProductionScan.serial_no)
.join(ProductionMaster, ProductionMaster.prod_code == Barcode.prod_code)
.filter(
sa.and_(
ProductionScan.date >= start_date,
ProductionScan.date <= end_date,
ProductionMaster.article.like(search),
# sa.or_(ProductionMaster.article.like(search1), ProductionMaster.article.like(search2))
)
)
.filter(Barcode.serial_no.isnot(None))
.with_entities(ProductionMaster.article.label('article'), Barcode.size.label('size'), sa.func.count(Barcode.size).label('count'))
.group_by(ProductionMaster.article, Barcode.size)
.all()
with_entities
返回一个新的查询,用给定的实体替换 SELECT 列表。
【讨论】:
您的解决方案运行良好,但我只需在查询语句之后和在我的代码中加入表之前添加.select_from(ProductionScan)
即可获得结果。
那么这两个在查询中的效果是一样的?以上是关于SQLAlchemy 仅从连接表中选择列的主要内容,如果未能解决你的问题,请参考以下文章