Me sierra que g
va a pasar del contexto de la petición al contexto de la aplicación en el frasco 0,10, lo que me hizo confundir sobre el uso previsto de g
.
Tengo entendido (para Flask 0.9) es que:
g
vive en el contexto de la solicitud, es decir, se crea de nuevo cuando las solicitudes comienzan y está disponible hasta que finalizag
está destinado a ser utilizado como un "pizarrón de solicitud", donde puedo poner cosas relevantes para la duración de la solicitud (es decir, establecer una bandera al comienzo de la solicitud y manejarla al final, posiblemente desde unbefore_request
/after_request
par)- Además de mantener el estado de nivel de solicitud, se
g
puede y se debe usar para la gestión de recursos, es decir, mantener conexiones de bases de datos, etc.
¿Cuál de estas oraciones ya no es verdadera en Flask 0.10? ¿Alguien puede señalarme un recurso que discuta las razones del cambio? ¿Qué debo usar como un "pizarrón de solicitud" en el Frasco 0.10? ¿Debería crear mi propio proxy local de subproceso específico de aplicación / extensión y llevarlo a la pila de contexto before_request
? ¿Cuál es el punto de la gestión de recursos en el contexto de la aplicación, si mi aplicación vive durante un tiempo prolongado (no como una solicitud) y, por lo tanto, los recursos nunca se liberan?
g
en 0.10, de lo contrario, parece que mucho código podría comenzar a desarrollar algunos errores tortuosos.flask.g
. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1Respuestas:
Los patrones de matraz avanzados , como los vincula Markus , explica algunos de los cambios
g
en 0.10:g
ahora vive en el contexto de la aplicación.g
lo que aún se puede usar para establecer banderas por solicitud sin cambiar el código.teardown_request
se llama. (La presentación de Armin explica que esto se debe a que cosas como crear conexiones de base de datos son tareas que configuran el entorno para la solicitud, y no deben manejarse dentrobefore_request
yafter_request
)fuente
app_ctx is None or app_ctx.app != self.app
es falso, el antiguo contexto de la aplicación parece reutilizarse? Esto no parece ser correcto, ya que el contexto de la aplicación "no se compartirá entre solicitudes" ...app.app_context()
? Si es así, debe tenerse en cuenta queapp_context()
crea una instancia de un nuevo contexto de aplicación en cada llamada; nunca reutiliza un contexto.app_ctx is not None and app_ctx.app == self.app
laapp_ctx = self.app.app_context()
línea no se ejecuta; soloself._implicit_app_ctx_stack.append(None)
se ejecuta en este caso.RequestContext
es empujado, entonces solo unoAppContext
es empujado. Pero si el modo de depuración está activado y falla una solicitud, Flask guarda el contexto , por lo que puede usarse con el depurador .None
se adjunta a_app_ctx_stack
, por lo que cuando la solicitud se está desglosando, sabe que aún no debe aparecerAppContext
. Lo mismo ocurre con el cliente de prueba, que retiene el contexto, por lo que puede ser inspeccionado.Como una adición a la información en este hilo: también me ha confundido un poco el comportamiento
flask.g
, pero algunas pruebas rápidas me han ayudado a aclararlo. Esto es lo que probé:Y aquí está la salida que da:
Como dijo el Y4Kman arriba, "Cada solicitud empuja un nuevo contexto de aplicación". Y como dicen los documentos de Flask , el contexto de la aplicación "no se compartirá entre las solicitudes". Ahora, lo que no se ha declarado explícitamente (aunque supongo que está implícito en estas declaraciones), y lo que mis pruebas muestran claramente, es que nunca debes crear explícitamente múltiples contextos de solicitud anidados dentro de un contexto de aplicación, porque
flask.g
(y co) no No tiene ninguna magia por la que funcione en los dos diferentes "niveles" de contexto, con diferentes estados existentes independientemente en los niveles de solicitud y solicitud.La realidad es que "contexto de aplicación" es potencialmente un nombre bastante engañoso, porque
app.app_context()
es un contexto por solicitud , exactamente igual al "contexto de solicitud" . Piense en ello como un "contexto de solicitud lite", solo requerido en el caso de que necesite algunas de las variables que normalmente requieren un contexto de solicitud, pero no necesita acceso a ningún objeto de solicitud (por ejemplo, cuando se ejecutan operaciones de base de datos por lotes en un script de shell). Si intenta extender el contexto de la aplicación para abarcar más de un contexto de solicitud, está buscando problemas. Entonces, en lugar de mi prueba anterior, debería escribir código como este con los contextos de Flask:Lo que dará los resultados esperados:
fuente