def getBeforePoint(userId):
today = datetime.now()
子查询 = (
db.session.query(
T_user_point.acquired_at、
M_promotion_code.valid_days、
T_user_promotion_code.promotion_code_id、
T_user_point.user_promotion_code_id、
T_user_promotion_code.user_promotion_code_id、
)
.join(T_user_promotion_code, T_user_point.user_promotion_code_id == T_user_promotion_code.user_promotion_code_id)
.join(M_promotion_code, T_user_promotion_code.promotion_code_id == M_promotion_code.promotion_code_id)
.filter(T_user_point.user_id == userId)
.subquery()
)
result = db.session.query(
subquery.c.acquired_at、
subquery.c.valid_days
).all()
loop_counter = 0
point_with_valid_days = 0
for row in result:
acquired_at = row.acquired_at
valid_days = row.valid_days
如果 valid_days 不是 None,则
valid_duration = timedelta(days=valid_days)
expiration_date = acquired_at + timedelta(days=valid_days)
point_expiration_date = func.cast(acquired_at + timedelta(days=valid_days), DATE)
if today < expiration_date:
point_with_valid_days = (
db.session.query(func.sum(T_user_point.point))
.join(subquery, T_user_point.user_promotion_code_id == subquery.c.user_promotion_code_id)
.filter(
T_user_point.user_id == userId、
T_user_point.is_deleted == False、
subquery.c.valid_days.isnot(None)、
今天 < point_expiration_date、
T_user_point.user_promotion_code_id == T_user_promotion_code.user_promotion_code_id
)
.scalar() 或 0
)
否则:
point_with_valid_days += 0
loop_counter += 1
print('point_with_valid_days', point_with_valid_days)
数据库中有 50 个积分的有效期已过(point_expiration_date 为 False),10 个积分的有效期未过(point_expiration_date 为 True)。
在上面的代码中,我以为 print('point_with_valid_days', point_with_valid_days) 将打印 10,但实际上它打印了 60。
我不知道我在代码中做错了什么。 谁能帮我找出代码中的错误?
你代码的主要问题在于循环内部对 point_with_valid_days
的处理方式。你每次循环都会重新计算 point_with_valid_days
的值,而不是累加它。这就是为什么你最终得到 60 而不是 10 的原因。
以下是你的代码存在的问题的详细解释:
-
循环内部重复计算: 在你的循环中,每次迭代都会执行
db.session.query(...)
来计算point_with_valid_days
。 即使当前积分的有效期已过,查询也会执行,并将之前所有有效积分的总和赋值给point_with_valid_days
。 -
未累加有效积分: 在
否则:
分支中,你只是简单地将 0 加到point_with_valid_days
上,而不是累加之前循环中计算出的有效积分。
为了解决这些问题,你需要修改循环内部的逻辑,以便只在积分有效时累加 point_with_valid_days
的值。
以下是修改后的代码:
def getBeforePoint(userId):
today = datetime.now()
# ... (子查询代码不变) ...
result = db.session.query(
subquery.c.acquired_at,
subquery.c.valid_days
).all()
loop_counter = 0
point_with_valid_days = 0 # 初始化总有效积分
for row in result:
acquired_at = row.acquired_at
valid_days = row.valid_days
if valid_days is not None:
expiration_date = acquired_at + timedelta(days=valid_days)
point_expiration_date = func.cast(expiration_date, DATE)
# 只在积分有效时计算并累加
if today < expiration_date:
valid_points = (
db.session.query(func.sum(T_user_point.point))
.join(subquery, T_user_point.user_promotion_code_id == subquery.c.user_promotion_code_id)
.filter(
T_user_point.user_id == userId,
T_user_point.is_deleted == False,
subquery.c.valid_days.isnot(None),
today < point_expiration_date,
T_user_point.user_promotion_code_id == T_user_promotion_code.user_promotion_code_id
)
.scalar() or 0
)
point_with_valid_days += valid_points # 累加有效积分
loop_counter += 1
print('point_with_valid_days', point_with_valid_days)
return point_with_valid_days # 返回总有效积分
通过以上修改,你的代码现在应该能够正确计算并返回用户的有效积分总和了。
标签:python,sqlalchemy From: 78557977