sqlmodel icon indicating copy to clipboard operation
sqlmodel copied to clipboard

How to check if string contains value? i.e. where x like "%value%"

Open Goldziher opened this issue 3 years ago • 6 comments

First Check

  • [X] I added a very descriptive title to this issue.
  • [X] I used the GitHub search to find a similar issue and didn't find it.
  • [X] I searched the SQLModel documentation, with the integrated search.
  • [X] I already searched in Google "How to X in SQLModel" and didn't find any information.
  • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [X] I already checked if it is not related to SQLModel but to Pydantic.
  • [X] I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • [X] I commit to help with one of those options 👆

Example Code

statement = select(Event).where(Event.user_public_id == user.public_id)
if suggested_by:
     statement.filter(Event.suggested_by.contains(suggested_by))

Description

using SQLAlchemy I would do this

if suggested_by:
     query.filter(Event.suggested_by.contains(suggested_by))

assuming I have a statement like this:

statement = select(Event).where(Event.user_public_id == user.public_id)
if suggested_by:
     statement.filter(Event.suggested_by.contains(suggested_by))

As seen above I still use the SQLAlchemy logic in the above because I couldn't figure out any way to do this with SQLModel. Is there any way to perform a where/like query with this library?

Operating System

macOS

Operating System Details

No response

SQLModel Version

0.0.4

Python Version

3.9.7

Additional Context

No response

Goldziher avatar Nov 08 '21 21:11 Goldziher

I am looking for a way to achieve this, too. In sqlalchemy, it is possible to do this with something like User.name.ilike(search), but I am using vscode with this option "python.analysis.typeCheckingMode": "basic" and it has squiggly lines on it. The work-around I have seems a bit messy. Hope something gets implemented to solve this soon. Other than that I really like sqlmodel

calvo-jp avatar Nov 10 '21 09:11 calvo-jp

Kindly try this, it work for me.

select(User).where(User.name.like(’%’+ keyword + ‘%’))

terrysclaw avatar Nov 10 '21 10:11 terrysclaw

Yup, as i stated in the OP, i can reach for the underlying sqlalchemy api and do this. But this doesn't give me the same kind of type safety and editor completion as I would get otherwise.

Goldziher avatar Nov 10 '21 13:11 Goldziher

Given this is a few months later, there may have been improvements in SQLModel. The following seems to work by importing col and explicitly wrapping the column before using contains.

select(Event).where(col(Event.suggested_by).contains(suggested_by)

johnziebro avatar Apr 05 '22 19:04 johnziebro

Thanks, @johnziebro your solution made it really simple also with custom queries.

query = select(User).where(and_(User.role_id == role.id, or_(col(User.first_name).contains(name), col(User.last_name).contains(name)))).order_by(User.first_name)

jonra1993 avatar Apr 26 '22 16:04 jonra1993

@johnziebro while your solution works beautifully, would it be possible to also make it case-insensitive?

mrsakkaro avatar Jun 30 '22 03:06 mrsakkaro

It did not worked for me (I mean vscode has squiggly lines on it too). But this worked for me:

...
from sqlmodel import column
...
_contents = session.query(Content).filter(column("link").contains("something")).order_by(ordering).offset(offset).limit(limit).all()

But it would be better with "Class.column" implementation :/

dmtea avatar Oct 07 '22 22:10 dmtea

@mrsakkaro A bit late, but using regexp_match(value, "i") instead of contains(value) does the trick.

marioax avatar Sep 16 '23 04:09 marioax