What is the best / correct way to create a url
which needs to be passed to sqlalchemy.create_engine
? https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine
My connection string looks similar to this:
con_str = "Driver={ODBC Driver 17 for SQL Server};Server=tcp:somedb.database.windows.net,1433;Database=somedbname;Uid=someuser;Pwd=some++pass=;Encrypt=yes;TrustServerCertificate=no"
If I do (Connecting to SQL Server 2012 using sqlalchemy and pyodbc):
import urllibimport sqlalchemy as saconnection_url = sa.engine.URL.create("mssql+pyodbc", query={"odbc_connect": urllib.parse.quote_plus(con_str)},)print(connection_url.render_as_string(hide_password=False))
I get this output:
mssql+pyodbc://?odbc_connect=Driver%3D%7BODBC+Driver+17+for+SQL+Server%7D%3BServer%3Dtcp%3Asomedb.database.windows.net%2C1433%3BDatabase%3Dsomedbname%3BUid%3Dsomeuser%3BPwd%3Dsome%2B%2Bpass%3D%3BEncrypt%3Dyes%3BTrustServerCertificate%3Dno
But if I do (How do I use SQLAlchemy create_engine() with password that includes an @):
connection_url = sa.engine.URL.create( drivername="mssql+pyodbc", username="someuser", password="some++pass=", host="tcp:somedb.database.windows.net", port=1433, database="somedbname", query={'driver': 'ODBC Driver 17 for SQL Server', 'encrypt': 'yes', 'trustservercertificate': 'no'},)print(connection_url.render_as_string(hide_password=False))
I get a different output:
mssql+pyodbc://someuser:some++pass%3D@[tcp:somedb.database.windows.net]:1433/somedbname?driver=ODBC+Driver+17+for+SQL+Server&encrypt=yes&trustservercertificate=no
Both of them work for general reads but for more obscure uses they produce different results.
For example, for a particular piece of code the former option works while the latter option throws:
('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Implicit conversion from data type nvarchar(max) to binary is not allowed. Use the CONVERT function to run this query. (257) (SQLExecDirectW)').
I am assuming the former is correct since the majority of StackOverflow answers provide it as an example. I am interested why different parameters produce such different results and where can I read about it on https://docs.sqlalchemy.org/?