我正在尝试使用Flask SQLAlchemy连接到Azure托管的SQL数据库。当我直接使用pyodbc.connect
时,一切正常,例如:
import pyodbc
# I got the ODBC connection string directly from Azure's connection strings for the db.
odbc_string = 'Driver={ODBC Driver 17 for SQL Server};Server=tcp:sql-server-for-capstone.database.windows.net,1433;Database=MastersCapstone;Uid={my username};Pwd={my super secure password here};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'
conn = pyodbc.connect(odbc_string)
# Works!
但是当我尝试使用Flask SQLAlchemy进行连接时,我得到了:
sqlalchemy.exc.OperationalError: (pyodbc.OperationalError) ('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]Neither DSN nor SERVER keyword supplied (0) (SQLDriverConnect)')
我用于通过SQLAlchemy连接的配置看起来像这样:
odbc_string = 'Driver={ODBC Driver 17 for SQL Server};Server=tcp:sql-server-for-capstone.database.windows.net,1433;Database=MastersCapstone;Uid={my username};Pwd={my super secure password here};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'
params = urllib.parse.quote_plus(odbc_string)
sqlalchemy_db_uri = f"mssql+pyodbc:///?odbc_connect={params}"
class Config:
# Database
SQLALCHEMY_DATABASE_URI = sqlalchemy_db_uri
然后我像在目录的__init__.py
文件中那样初始化应用程序:
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from src.python.server.config import Config
db = SQLAlchemy()
migrate = Migrate(compare_type=True)
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
migrate.init_app(app, db)
with app.app_context():
from src.python.server import routes, models
return app
最后,在终端中运行以下命令时出现错误:
flask db migrate
[请注意,当我使用PostgreSQL数据库时,一切正常。有谁知道为什么会这样?我很困!
附加信息:在终端中运行odbcinst -j
的输出:
unixODBC 2.3.7
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /Users/jordan/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
整个堆栈跟踪:
Traceback (most recent call last):
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2285, in _wrap_pool_connect
return fn()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 303, in unique_connection
return _ConnectionFairy._checkout(self)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 773, in _checkout
fairy = _ConnectionRecord.checkout(pool)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 492, in checkout
rec = pool._do_get()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 238, in _do_get
return self._create_connection()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 308, in _create_connection
return _ConnectionRecord(self)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 437, in __init__
self.__connect(first_connect_check=True)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 657, in __connect
pool.logger.debug("Error on connect(): %s", e)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
compat.raise_(
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
raise exception
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 652, in __connect
connection = pool._invoke_creator(self)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py", line 114, in connect
return dialect.connect(*cargs, **cparams)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 490, in connect
return self.dbapi.connect(*cargs, **cparams)
pyodbc.OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]Neither DSN nor SERVER keyword supplied (0) (SQLDriverConnect)')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/jordan/Coding/survey-app/venv/bin/flask", line 8, in <module>
sys.exit(main())
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/flask/cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func
return f(get_current_context(), *args, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/flask/cli.py", line 426, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/flask_migrate/cli.py", line 89, in migrate
_migrate(directory, message, sql, head, splice, branch_label, version_path,
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/flask_migrate/__init__.py", line 96, in wrapped
f(*args, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/flask_migrate/__init__.py", line 210, in migrate
command.revision(config, message, autogenerate=True, sql=sql,
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/alembic/command.py", line 214, in revision
script_directory.run_env()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/alembic/script/base.py", line 489, in run_env
util.load_python_file(self.dir, "env.py")
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/alembic/util/pyfiles.py", line 98, in load_python_file
module = load_module_py(module_id, path)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/alembic/util/compat.py", line 184, in load_module_py
spec.loader.exec_module(module)
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "migrations/env.py", line 96, in <module>
run_migrations_online()
File "migrations/env.py", line 81, in run_migrations_online
with connectable.connect() as connection:
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2218, in connect
return self._connection_cls(self, **kwargs)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 103, in __init__
else engine.raw_connection()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2317, in raw_connection
return self._wrap_pool_connect(
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2288, in _wrap_pool_connect
Connection._handle_dbapi_exception_noconnection(
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1554, in _handle_dbapi_exception_noconnection
util.raise_(
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
raise exception
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2285, in _wrap_pool_connect
return fn()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 303, in unique_connection
return _ConnectionFairy._checkout(self)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 773, in _checkout
fairy = _ConnectionRecord.checkout(pool)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 492, in checkout
rec = pool._do_get()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 238, in _do_get
return self._create_connection()
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 308, in _create_connection
return _ConnectionRecord(self)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 437, in __init__
self.__connect(first_connect_check=True)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 657, in __connect
pool.logger.debug("Error on connect(): %s", e)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
compat.raise_(
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
raise exception
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 652, in __connect
connection = pool._invoke_creator(self)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py", line 114, in connect
return dialect.connect(*cargs, **cparams)
File "/Users/jordan/Coding/survey-app/venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 490, in connect
return self.dbapi.connect(*cargs, **cparams)
sqlalchemy.exc.OperationalError: (pyodbc.OperationalError) ('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]Neither DSN nor SERVER keyword supplied (0) (SQLDriverConnect)')
(Background on this error at: http://sqlalche.me/e/e3q8)
哦我的神。不是SQLALCHEMY_DATABASE_URI
,而是SQLALCHEMY_DATABASE_URL
。有L。这与PostgreSQL一起工作的方式超出了我。