fix: correct SQLAlchemy join condition to resolve MaterialBase AttributeError

This commit is contained in:
DXC
2026-03-20 10:06:22 +08:00
parent 990399a408
commit 34629b432a
2 changed files with 114 additions and 27 deletions

View File

@ -6,7 +6,7 @@ from app.models.inbound.buy import StockBuy
from app.models.inbound.semi import StockSemi
from app.models.inbound.product import StockProduct
from app.models.base import MaterialBase
from sqlalchemy import desc, func, nullslast, asc, or_
from sqlalchemy import desc, func, nullslast, asc, or_, and_
class TransService:
@ -193,23 +193,66 @@ class TransService:
# 如果有关键词,需要联表搜索物料名称和规格型号
if keyword:
# 子查询:关联 material_base 表获取物料名称和规格型号
material_join = db.session.query(
TransBorrow.id
).join(
MaterialBase,
TransBorrow.sku == MaterialBase.sku
).filter(or_(
MaterialBase.name.ilike(f'%{keyword}%'),
MaterialBase.spec_model.ilike(f'%{keyword}%')
)).subquery()
# TransBorrow 通过 source_table + stock_id 关联到不同库存表,再关联到 MaterialBase
# 需要使用 union 或分别查询后合并
# 主搜索条件借用人、SKU、单号 + 物料名称规格型号
# 查询 stock_buy 路径匹配的名称/规格
buy_match = db.session.query(TransBorrow.id).join(
StockBuy, and_(
TransBorrow.stock_id == StockBuy.id,
TransBorrow.source_table == 'stock_buy'
)
).join(
MaterialBase, StockBuy.base_id == MaterialBase.id
).filter(
or_(
MaterialBase.name.ilike(f'%{keyword}%'),
MaterialBase.spec_model.ilike(f'%{keyword}%')
)
).subquery()
# 查询 stock_semi 路径匹配的名称/规格
semi_match = db.session.query(TransBorrow.id).join(
StockSemi, and_(
TransBorrow.stock_id == StockSemi.id,
TransBorrow.source_table == 'stock_semi'
)
).join(
MaterialBase, StockSemi.base_id == MaterialBase.id
).filter(
or_(
MaterialBase.name.ilike(f'%{keyword}%'),
MaterialBase.spec_model.ilike(f'%{keyword}%')
)
).subquery()
# 查询 stock_product 路径匹配的名称/规格
product_match = db.session.query(TransBorrow.id).join(
StockProduct, and_(
TransBorrow.stock_id == StockProduct.id,
TransBorrow.source_table == 'stock_product'
)
).join(
MaterialBase, StockProduct.base_id == MaterialBase.id
).filter(
or_(
MaterialBase.name.ilike(f'%{keyword}%'),
MaterialBase.spec_model.ilike(f'%{keyword}%')
)
).subquery()
# 合并三种来源的匹配 ID
all_matches = db.session.query(buy_match.id).union(
db.session.query(semi_match.id),
db.session.query(product_match.id)
).subquery()
# 主搜索条件借用人、SKU、单号 + 物料名称/规格匹配
keyword_conditions = or_(
TransBorrow.borrower_name.ilike(f'%{keyword}%'),
TransBorrow.sku.ilike(f'%{keyword}%'),
TransBorrow.borrow_no.ilike(f'%{keyword}%'),
TransBorrow.id.in_(material_join) # 匹配物料名称/规格型号的记录
TransBorrow.id.in_(all_matches)
)
q = q.filter(keyword_conditions)