簡體   English   中英

如何使用 SQLite 在 SQLAlchemy 中執行 REGEXP_REPLACE?

[英]How can I do REGEXP_REPLACE in SQLAlchemy with SQLite?

我有一個 Postgres 支持的網站,並使用REGEXP_REPLACE替換某些列中值的第一個實例。 這可以。 問題出現在我需要運行 CI 的地方,由於一個原因和另一個原因(Github 操作和 Windows VM 的限制),我不能在我的測試中使用 Postgres。

選擇 SQLite 產生了一些測試失敗,我意識到 SQLite 沒有內置REGEXP_REPLACE

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such function: regexp_replace
E       [SQL: SELECT job_site.created_at AS job_site_created_at, ..., job_site.neighborhood_id AS job_site_neighborhood_id 
E       FROM job_site 
E       WHERE regexp_replace(job_site.name, ?, ?) = ?]
E       [parameters: (' - ', ':', 'BGS:NEEA - 1894 - 05700 Brown Islands Suite 681')]
E       (Background on this error at: http://sqlalche.me/e/e3q8)

如何在 SQLAlchemy 中將此 function 添加到 SQLite?

最終解決方案是將regexp_replace注冊為GenericFunction ( docs ),並添加在與 SQLite 引擎一起運行時使用的特定方言編譯器 ( docs )。

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.functions import GenericFunction


class regexp_replace(GenericFunction):
    type = String
    identifier = "regexp_replace"


@compiles(regexp_replace, "sqlite")
def visit_regexp_replace(element, compiler, **kw):
    column, pattern, replacement = list(element.clauses)
    return (
        f"SUBSTR({column}, 0, INSTR ({column}, '{pattern.value}')) "
        f"|| '{replacement.value}' "
        f"|| SUBSTR({column}, INSTR ({column}, '{pattern.value}') + LENGTH('{pattern.value}'))"
    )

也可以按照此處的建議使用 SQLite C 擴展,但我並沒有考慮讓它發揮作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM