Peewee中如何获取指定用户无UserCoTransaction关联的UserTransaction?
解决Peewee获取用户未关联CoTransaction的交易记录问题
嘿,我来帮你搞定这个Peewee的问题!首先我先假设下你的模型结构(毕竟你没贴出来,按常见的关联关系来推导),这样更容易讲清楚解决方案:
from peewee import * import datetime db = SqliteDatabase('your_app.db') class User(Model): username = CharField(unique=True) class Meta: database = db class UserTransaction(Model): user = ForeignKeyField(User, backref='transactions') amount = DecimalField() created_at = DateTimeField(default=datetime.datetime.now) class Meta: database = db class UserCoTransaction(Model): transaction = ForeignKeyField(UserTransaction, backref='co_transactions') co_user = ForeignKeyField(User) class Meta: database = db
错误原因分析
你遇到的AttributeError: 'BackrefAccessor' object has no attribute 'count',大概率是因为你尝试直接在集合反向引用(比如user.transactions)上链式调用聚合方法。Peewee的BackrefAccessor本身不是一个查询结果集,它只是生成查询的入口,不能直接调用count()这类聚合方法。
正确实现方式
下面给你两种高效的实现方法,任选其一都能解决需求:
方法1:子查询排除已关联交易
这种方式性能最优,尤其是数据量较大时,数据库会自动优化子查询逻辑:
# 假设你已经获取了目标用户 target_user = User.get(User.id == 123) # 先拿到所有关联了UserCoTransaction的交易ID associated_tx_ids = UserCoTransaction.select(UserCoTransaction.transaction_id) # 筛选该用户所有未被关联的交易 unlinked_transactions = UserTransaction.select().where( (UserTransaction.user == target_user) & (~UserTransaction.id.in_(associated_tx_ids)) ) # 遍历结果示例 for tx in unlinked_transactions: print(f"交易ID: {tx.id}, 金额: {tx.amount}")
方法2:左连接筛选无关联记录
通过左连接UserCoTransaction,筛选那些没有匹配关联记录的交易(即关联表字段为NULL的记录):
unlinked_transactions = (UserTransaction .select(UserTransaction) .join(UserCoTransaction, JOIN.LEFT_OUTER, on=(UserTransaction.id == UserCoTransaction.transaction_id)) .where( (UserTransaction.user == target_user) & (UserCoTransaction.id.is_null()) ) .distinct()) # 避免出现重复记录
更简洁的链式写法
利用用户的反向引用transactions,可以进一步简化代码:
unlinked_transactions = target_user.transactions.where( ~UserTransaction.id.in_(UserCoTransaction.select(UserCoTransaction.transaction_id)) )
额外提示
如果要检查单条交易是否有关联的UserCoTransaction,正确写法是这样的:
tx = UserTransaction.get_by_id(456) has_co_tx = UserCoTransaction.select().where(UserCoTransaction.transaction == tx).exists()
注意:单条记录的反向引用(比如tx.co_transactions)是Query对象,可以直接调用count();但集合反向引用(比如user.transactions)是BackrefAccessor,必须先构建查询再操作。
内容的提问来源于stack exchange,提问作者kramer65
相关产品推荐
相关产品推荐

