sqlalchemy:在filter()中应用拆分

qoefvg9y  于 2021-08-13  发布在  Java
关注(0)|答案(1)|浏览(266)

我有一个 checkout 表,其中我将“cart items”存储在“cartids”列中,值用逗号分隔。例如)checkout.cartid<56,54>
要在python上使用这些数据,我需要首先将其拆分,并使其成为一个数组,以便在过滤器中应用它,这并不像我预期的那样工作。请参阅以下内容以获得更好的理解。

db.query(checkout, cart).filter(checkout.userId == userId, cart.id.in_(checkout.CartId.split(','))).all()

我通过在筛选器中使用“contains”解决了这个问题,但是如果数据库变大,我确信它会导致错误,因为它会捕获多个值,例如“64”将捕获640、641、642。。等等。
有什么办法可以得到我想要的数据吗?我查了好几篇文章,但找不到答案。基本上我想检索数据如下:

checkout = {

  "id" : 1,
   ....
   "carts": [
      {'id': 1, 'price': 12, 'title': 'iPad'},
      {'id': 2, 'price': 11, 'title': 'iPhone'}
   ]

}
au9on6nz

au9on6nz1#

在我回答你的问题之前,请给我一个简短的评论。如果您需要在一个字段中有多个id项,这可能意味着您还没有完全考虑到db设计。您所描述的是一个多对多关系,其中一个购物车包含多个项目,每个项目可以由多个购物车包含(例如,不同的客户可以将相同的项目放入他们的购物车)
在这种情况下,您需要在两个表之间有一个连接表,其中包含购物车id和商品id,每个组合一行。这在许多不同的博客文章和视频中都有解释,比如这个。
这种方法的好处是,您可以通过外键约束强制cart item id存在,您可以索引此关系,这意味着mysql不必检查整个表中的匹配项,而只能在子集中搜索,而且检查数字比检查和拆分字符串快得多。
但是,假设您仍然希望这样做,那么我建议您结合使用正则表达式匹配和字符串串联:


# Let the regex pattern be built dynamically by the query

# Look for the cartId and let it be either at the start of the string,

# or directly follow a comma, and let it be at the end of the string

# or be followed by a comma

cart_id_match_regex = func.concat('(^|,)', cart.id, '(,$)')

db.query(checkout, cart).filter(
    checkout.userId == userId,
    func.regexp_like(checkout.CartId, cart_id_match_regex)
).all()

相关问题