0

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 urllib import sqlalchemy as sa connection_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/?

0

1 Answer 1

0

I don't use this database or driver but there is some information in the docs about both your examples. It seems that they are both supported.

pass-through-exact-pyodbc-string

  • the docs do not use urllib.parse.quote_plus in this case, maybe try it without it? maybe it falls back to a different driver?

hostname-connections

  • their "trustservercertificate" is written "TrustServerCertificate", this might not matter as the docs only mention "driver" as being special
Sign up to request clarification or add additional context in comments.

1 Comment

urllib.parse.quote_plus is there for passwords with "funny" symbols. It can work without it just as well, indeed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.