簡體   English   中英

Flask-SQLAlchemy中的LocalProxy對象

[英]LocalProxy objects in Flask-SQLAlchemy

我在Flask應用程序中使用了很多werkzeug.local.LocalProxy對象。 它們應該是對象的完美替代品,但實際上並非如此,因為它們無法正確響應type()或instanceof()。

SQLAlchemy根本不喜歡它們。 如果我對SQLAlchemy記錄創建LocalProxy,則SQLAlchemy會將其視為“無”。 如果我將LocalProxy傳遞給一個簡單的類型,它只是說這是錯誤的類型。

這是Flask-SQLAlchemy在LocalProxy上遇到麻煩的示例

你們如何處理這個問題? 只是經常調用_get_current_object()? 如果SQLAlchemy或Flask-SQLAlchemy可以自動更優雅地自動處理這些LocalProxy對象,那將非常酷,尤其是考慮到Flask-Login使用它們,並且幾乎每個人都使用它們,對嗎?

我正在考慮將此函數添加到我的項目中以對其進行處理,並在將它們傳遞給sqlalchemy之前將其中的任何本地代理包裝起來:

from werkzeug.local import LocalProxy

def real(obj):
    if isinstance(obj, LocalProxy):
        return obj._get_current_object()
    return obj

我修補了SQLAlchemy使用的驅動程序,但是我擔心它不是最通用的解決方案。

from flask_sqlalchemy import SQLAlchemy as FlaskSQLAlchemy
from sqlalchemy.engine import Engine
from werkzeug.local import LocalProxy


class SQLAlchemy(FlaskSQLAlchemy):
    """Implement or overide extension methods."""

    def apply_driver_hacks(self, app, info, options):
        """Called before engine creation."""
        # Don't forget to apply hacks defined on parent object.
        super(SQLAlchemy, self).apply_driver_hacks(app, info, options)

        if info.drivername == 'sqlite':
            from sqlite3 import register_adapter

            def adapt_proxy(proxy):
                """Get current object and try to adapt it again."""
                return proxy._get_current_object()

            register_adapter(LocalProxy, adapt_proxy)

        elif info.drivername == 'postgresql+psycopg2':  # pragma: no cover
            from psycopg2.extensions import adapt, register_adapter

            def adapt_proxy(proxy):
                """Get current object and try to adapt it again."""
                return adapt(proxy._get_current_object())

            register_adapter(LocalProxy, adapt_proxy)

        elif info.drivername == 'mysql+pymysql':  # pragma: no cover
            from pymysql import converters

            def escape_local_proxy(val, mapping):
                """Get current object and try to adapt it again."""
                return converters.escape_item(
                    val._get_current_object(),
                    self.engine.dialect.encoding,
                    mapping=mapping,
                )

            converters.encoders[LocalProxy] = escape_local_proxy

原始資料可以在這里找到。

暫無
暫無

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

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