如何在Peewee的SelectQuery中为表达式实现数组切片?
Got it, let's tackle this problem. You're trying to replicate the raw PostgreSQL query that slices the array returned by regexp_match directly in the database—avoiding the hassle of parsing array strings in your application code. Here's how to do it properly with SQLAlchemy ORM:
The Correct Query Syntax
Instead of just selecting the REGEXP_MATCH result directly, use Python's bracket notation [1] on the function expression. This tells SQLAlchemy to generate the array slicing syntax PostgreSQL expects. Here's the code:
from sqlalchemy import func as fn # Build the select query with array slicing query = ZbxHost.select( ZbxHost.name, # Use [1] to fetch the first element of the regexp_match result array fn.REGEXP_MATCH(ZbxHost.name, r'^ATM-\w{5}-(\S+)$')[1].label('extracted_part') )
Why This Works
In PostgreSQL, regexp_match returns an array of matched capture groups, and you access elements with (regexp_match(...))[1]. SQLAlchemy recognizes that applying [1] to the func.REGEXP_MATCH expression should translate directly to this SQL syntax.
The .label('extracted_part') is optional but useful—it gives the computed column a clear name, making it easier to reference in your result rows.
Example of Executing the Query
If you're using a SQLAlchemy session, you can run the query and iterate over results like this:
# Assuming your session is configured as db.session for row in db.session.execute(query): print(f"Host Name: {row.name} | Extracted Part: {row.extracted_part}")
Key Notes
- Use raw strings (prefix with
r) for your regex pattern in Python to avoid double-escaping backslashes (e.g.,r'^ATM-\w{5}-(\S+)$'instead of'^ATM-\\w{5}-(\\S+)$'). - PostgreSQL arrays are 1-indexed, so
[1]targets the first capture group from your regex. For additional groups, use[2],[3], etc.
This approach ensures all processing happens in the database, so you get the exact value you need without post-processing array strings in your app.
内容的提问来源于stack exchange,提问作者dd_reyman

