Django 和 SQLAlchemy 之间比较
1. Django
django的orm是活动记录的方式来实现的, 数据库中的每行数据都直接隐射到代码对象中
2. sqlalchemy
SQLAlcyhemy 是数据映射实现,数据库结构和对象结构之间存在间隙,必须使用另外的持久层来保持与数据库的交互(例如保存对象),不会捆绑并强迫严格遵照活动记录来考量。适用于复杂的查询。
总结
Django 适用于所有常规 CRUD 操作。会自动生成主键,会自动提交等。Django Model 更简洁一些。例如对于类关联,Django 只要直接声明外键,就自动产生关联对象,而 SQLAlcyhemy 要定义外键、relationship 对象,如果有多个外键还要自己指定 join 规则……
flask请求的生命周期
1. 创建ctx = requestContext封装request,session
2. 创建app_ctx = AppContext封装app,g
3. 执行ctx.push将ctx,app_ctx放入local
4. 执行before_request
5. 执行视图函数
6. 执行after_request, 加密session到cookie
7. 销毁ctx和app_ctx
11个钩子信号
'''
请求到来时
1. def wsgi_app--> ctx.push() --> app_ctx 被push到local, 触发appcontext_pushed 信号
ctx.push里面出问题的捕获信号
1.1 def wsgi_app --> def handle_exception --> got_request_exception.send(self, exception=e)
1.2 after_request
1.3 request_finished
2. def wsgi_app--> self.full_dispatch_request() --> before_first_request
3. def wsgi_app--> self.full_dispatch_request() --> request_started 信号
4. def wsgi_app--> self.preprocess_request() --> preprocess_request
5. def wsgi_app--> self.preprocess_request() --> before_request
6. 视图函数
6.1 render_template --> _render --> before_render_template信号
6.2 渲染模板
6.3 render_template --> _render --> template_rendered.send信号
7. def full_dispatch_request --> def finalize_request --> def process_response -> after_request
8. def full_dispatch_request --> def finalize_request --> request_finished.send(self, response=response)信号
9. pop --> do_teardown_request --> teardown_request_funcs(exc)
10. def wsgi_app --> ctx.pop(error) --> do_teardown_request --> request_tearing_down.send(self, exc=exc)信号
11. def wsgi_app --> ctx.pop(error) --> app_ctx.pop(exc) --> appcontext_popped.send(self.app) 信号
'''
'''
其他:
一, 视图函数模板渲染
1.1 render_template --> _render --> before_render_template信号
1.2 渲染
1.3 render_template --> _render --> template_rendered.send信号
二. 异常处理
ctx.push时出问题的捕获信号
1.1 def wsgi_app --> def handle_exception --> got_request_exception.send(self, exception=e)
1.2 after_request
1.3 request_finished
'''
简述Flask上下文管理流程?
当 Flask 应用程序启动时,会自动创建应用程序上下文,该上下文是全局唯一的。 当有请求到达 Flask 应用程序时,Flask 会先创建一个请求上下文,并将其绑定到当前线程中。 在请求上下文中,可以访问一些全局对象,如 request、g、current_app 等。这些对象都是线程独立的,不同线程之间互不干扰。 请求上下文中还包含了一些请求相关的信息,如请求头、请求体、请求参数等。 在请求处理过程中,可以通过 g 对象在不同函数之间共享数据,但需要注意避免出现线程安全问题。 请求处理完毕后,Flask 会自动销毁请求上下文,将其从当前线程中解绑,同时清除应用程序上下文。
Flask中的g的作用?
在 Flask 中,g 是一个特殊的全局变量,用于在请求处理过程中共享数据。g 的作用是在同一请求的不同函数之间传递数据,而无需显式地传递参数。
g 存储在当前请求的上下文中,因此它是线程安全的,并且在同一请求的任何地方都可以访问。
使用 g 可以解决以下场景的问题:
共享数据库连接或其他资源:在处理请求时,通常需要与数据库或其他外部资源进行交互。为了避免在每个函数中重复创建和销毁连接的开销,可以将连接存储在 g 中,在不同的函数中复用同一个连接。
from flask import g
@app.route('/')
def index():
if 'db' not in g:
g.db = connect_to_database()
# 使用 g.db 进行数据库操作
return 'Hello, World!'
临时存储请求相关的数据:在请求处理过程中,可能会产生一些临时数据,需要在多个函数之间共享。例如,验证用户身份并将用户信息存储在 g 中,以便后续的处理函数可以直接访问用户信息。
from flask import g, request
@app.before_request
def authenticate():
user = authenticate_user(request)
g.user = user
@app.route('/')
def index():
# 可以访问 g.user 获取当前用户信息
return 'Hello, {}!'.format(g.user.username)
需要注意的是,g 的生命周期仅限于当前请求,一旦请求处理完毕,g 中存储的数据会被自动清除。因此,不要将重要的持久化数据存储在 g 中,而应该使用其他方式进行存储,如数据库或会话对象等。
Flask-SQLAlchemy的优化
Flask-SQLAlchemy 在以下方面对 SQLAlchemy 进行了优化:
上下文管理:Flask-SQLAlchemy 与 Flask 上下文管理器的集成,确保在请求处理期间正确管理数据库连接和事务。它提供了自动打开和关闭数据库连接的功能,而无需手动管理这些细节。这样可以减少因未正确管理连接而导致的资源泄漏和性能问题。
查询结果缓存:Flask-SQLAlchemy 支持查询结果的缓存,可避免重复执行相同查询导致的性能损耗。通过使用缓存,可以在多次查询相同数据时,直接从缓存中获取结果,而无需再次访问数据库。
批量插入:Flask-SQLAlchemy 提供了批量插入的支持,可以在一次数据库操作中插入多个记录,而不是逐条插入。这种批量插入的方式可以显著提高插入大量数据的性能,减少了每次插入操作的开销。
延迟加载:Flask-SQLAlchemy 默认使用的是延迟加载(Lazy Loading)模式,即在需要访问关联对象时才从数据库中加载相关数据。这种延迟加载的机制减少了不必要的数据库查询,从而提高了性能。
查询优化:Flask-SQLAlchemy 提供了一些查询优化的功能,如索引、查询缓存等。可以使用索引来提高查询的效率,通过缓存查询结果可以减少数据库访问的次数。
事务管理:Flask-SQLAlchemy 提供了对数据库事务的支持。它通过上下文管理器来自动处理事务的开始、提交和回滚,确保数据的一致性和完整性。
总的来说,Flask-SQLAlchemy 在连接管理、查询结果缓存、批量插入、延迟加载、查询优化和事务管理等方面对 SQLAlchemy 进行了优化。这些优化措施可以提高数据库操作的效率和性能,减少不必要的开销,从而改善应用程序的响应速度和用户体验。