我有一个 python Flask Web 应用程序,当页面加载时,连接到我们的 SQL Server DB 并将某些表保存为 Panda 数据框架。此操作必须在页面加载时发生。我在连接到服务器和数据库时遇到问题。在本地,一切都运行得很好,所以我知道这是服务器端问题。我们为 Web 应用程序设置了 VNet 集成,但遇到了奇怪且不一致的错误。
我们使用的 SQLAlchemy 连接字符串如下:
user = os.environ["USER_NAME"]
password = os.environ["PASSWORD"]
hostName = os.environ["HOSTNAME"]
port = os.environ["SQLPORT"]
db = os.environ["DATABASE"]
# Establishing the database connection URI
database_uri = f"mssql+pyodbc://{user}:{password}@{hostName}:{port}/{db}?driver=ODBC+Driver+17+for+SQL+Server"
engine = create_engine(database_uri)
我们最近了解到主机名给我们带来了问题。我在本地使用的内容在网络应用程序中不起作用(主机的缩写)。我们尝试了两种可能的解决方案。一个是数字地址,不起作用,另一个是全名。
当我重新启动网络应用程序时,主机名的全名起作用。然而,它不再起作用了。
今天早上,我收到了同样的 SQL Server 连接错误:
sqlalchemy.exc.OperationalError: (pyodbc.OperationalError) ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
然后我尝试将主机名切换回数字地址,但仍然无法正常工作。当我将其切换回全名并重新启动应用程序时,它起作用了,并且我能够在代码出现错误之前通信几条消息(与状态管理相关的内容尚未实现,因为该应用程序正在测试中,而且我们只有一个实例)。然而,当我再次重新加载页面时,我开始再次收到相同的 SQL 连接错误。我很困惑为什么当主机名变量切换为全名并重新启动应用程序时它会工作两次,以及为什么在其他情况下它根本不起作用。目前,站点和主机名环境变量处于网络应用程序工作时的状态,只知道相同的错误仍然存在,我不知道如何解决它。我也无法检查应用程序日志,因为应用程序由于 SQL Server 连接而无法启动
sqlalchemy.exc.OperationalError: (pyodbc.OperationalError) ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]登录超时已过期 (0) (SQLDriverConnect)')
上述错误表示登录超时问题,由于使用 sql 与
web app
和 sql sever
的连接时间而发生。以下代码将 VNET 与 Azure SQL Database 结合使用,并为 Azure 应用服务和 Azure SQL Database 创建虚拟网络,成功检索数据,如下面的输出所示。
from flask import Flask, jsonify
import pyodbc
import pandas as pd
app = Flask(__name__)
connection_params = {
'Driver': '{ODBC Driver 17 for SQL Server}',
'Server': 'servername.database.windows.net',
'Database': 'DatabaseName',
'Uid': 'UidName',
'Pwd': 'Pwd',
'Encrypt': 'yes',
'TrustServerCertificate': 'no',
'Connection Timeout': '30'
}
def connect_to_sql_server():
try:
conn = pyodbc.connect(**connection_params)
return conn
except pyodbc.Error as e:
print("Error connecting to Azure SQL Server:", e)
return None
def fetch_data_as_dataframe(table_name):
conn = connect_to_sql_server()
if conn:
try:
query = f"SELECT * FROM {table_name};"
df = pd.read_sql(query, conn)
return df
except pyodbc.Error as e:
print("Error fetching data from SQL Server:", e)
return None
finally:
conn.close()
else:
return None
@app.route('/get_data/<table_name>')
def get_data(table_name):
df = fetch_data_as_dataframe(table_name)
if df is not None:
return jsonify(df.to_dict(orient='records'))
else:
return jsonify({'error': 'Failed to fetch data from the specified table.'}), 500
@app.errorhandler(Exception)
def handle_exception(e):
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)