我们有一个正在运行的 Web 应用程序,需要在请求期间连接到我们的 Azure SQL 数据库。为了使查询数据库更容易,我们使用 SQL Alchemy 和 pyodbc。
我们有一些想要实现的目标:
首先,为了确保我们为每个请求打开一个新会话,我们可以将请求函数包装到装饰器中,以确保创建并随后销毁新会话。
为了确保我们的会话可以从整个应用程序轻松访问,而不必在每个函数调用中移交它,我们使用单例模式。但是,由于我们运行多个线程来同时处理多个请求,因此我们必须确保会话对象不存在竞争条件。
SQL Alchemy 有一个很棒的实用程序可以让这一切变得更容易:作用域会话。
要使用它,我们将连接工厂包装到scoped_session() 调用中:
from urllib.parse import quote_plus from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, scoped_session connection_string = "..." engine = create_engine("mssql+pyodbc:///?odbc_connect={}".format(quote_plus(connection_string)) session_factory = sessionmaker(bind=engine) Session = scoped_session(session_factory)
现在,每当我们想要使用会话时,我们只需调用 Session() 即可,SQL Alchemy 确保我们重用现有的会话对象。如果完成,我们可以调用 Session.remove() 来关闭会话。 SQL Alchemy 无法判断线程是否已完成,因此我们必须自己执行此操作。
有一些帖子描述了如何使用访问令牌设置与 Azure SQL 数据库的连接,但最好的资源是 SQL Alchemy 文档本身。
让我们一起看一下细节。首先,我们需要一个连接字符串。由于我们希望依赖托管身份(或 Azure CLI 进行本地开发),因此我们不会将任何凭据放入连接字符串中:
驱动程序={ODBC Driver 18 for SQL Server};数据库=YOUR_DB;服务器=tcp:you.database.windows.net,1433;加密=是;TrustServerCertificate=no;连接超时=30
我们的总体计划是:
现在,让我们看一下代码:
from urllib.parse import quote_plus from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, scoped_session connection_string = "..." engine = create_engine("mssql+pyodbc:///?odbc_connect={}".format(quote_plus(connection_string)) session_factory = sessionmaker(bind=engine) Session = scoped_session(session_factory)
这样,我们就实现了我们的目标。使用scoped_session(),我们不需要每次收到请求时都打开一个新会话(这将为我们处理),但我们应该在最后关闭会话,这样我们就不会有太多悬空会话。
我们还使用我们自己的身份(对于本地开发人员)或 Web 服务的托管身份连接到 SQL 数据库。每次创建新连接时,我们都会修改连接字符串。
非常感谢 David 帮助我弄清楚范围会话的概念。
以上是使用 Entra ID 令牌连接到 SQL Alchemy 中的 Azure SQL 数据库的详细内容。更多信息请关注PHP中文网其他相关文章!