[英]SqlAlchemy equivalent of pyodbc connect string using FreeTDS
以下作品:
import pyodbc
pyodbc.connect('DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;')
以下失敗:
import sqlalchemy
sqlalchemy.create_engine("mssql://myuser:mypwd@my.db.server:1433/mydb?driver=FreeTDS& odbc_options='TDS_Version=8.0'").connect()
上面的錯誤消息是:
DBAPIError :(錯誤)('08001','[08001] [unixODBC] [FreeTDS] [SQL Server]無法連接到數據源(0)(SQLDriverConnectW)')無無
有人可以指點我正確的方向嗎? 有沒有辦法告訴sqlalchemy將特定的連接字符串傳遞給pyodbc?
請注意:我希望保持此DSN-less。
@Singletoned的例子不適用於SQLAlchemy 0.7.2。 從SQLAlchemy文檔連接到SQL Server :
If you require a connection string that is outside the options presented above, use the odbc_connect keyword to pass in a urlencoded connection string. What gets passed in will be urldecoded and passed directly.
為了使它工作,我使用:
import urllib
quoted = urllib.quote_plus('DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;')
sqlalchemy.create_engine('mssql+pyodbc:///?odbc_connect={}'.format(quoted))
這也適用於Sybase。
注意:在python 3中,urllib模塊已拆分為多個部分並重命名。 因此,這行在python 2.7中:
quoted = urllib.quote_plus
必須在python3中更改為此行:
quoted = urllib.parse.quote_plus
我仍然對在sqlalchemy create_engine
語句中的一行中執行此操作感興趣,但我發現此處詳細說明了以下解決方法:
import pyodbc, sqlalchemy
def connect():
pyodbc.connect('DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;')
sqlalchemy.create_engine('mssql://', creator=connect)
更新 :解決我在自己的評論中提出的關於無法將參數傳遞給連接字符串的問題。 如果需要在運行時動態連接到不同的數據庫,以下是一般解決方案。 我只將數據庫名稱作為參數傳遞,但可以根據需要輕松使用其他參數:
import pyodbc
import os
class Creator:
def __init__(self, db_name='MyDB'):
"""Initialization procedure to receive the database name"""
self.db_name = db_name
def __call__(self):
"""Defines a custom creator to be passed to sqlalchemy.create_engine
http://stackoverflow.com/questions/111234/what-is-a-callable-in-python#111255"""
if os.name == 'posix':
return pyodbc.connect('DRIVER={FreeTDS};'
'Server=my.db.server;'
'Database=%s;'
'UID=myuser;'
'PWD=mypassword;'
'TDS_Version=8.0;'
'Port=1433;' % self.db_name)
elif os.name == 'nt':
# use development environment
return pyodbc.connect('DRIVER={SQL Server};'
'Server=127.0.0.1;'
'Database=%s_Dev;'
'UID=user;'
'PWD=;'
'Trusted_Connection=Yes;'
'Port=1433;' % self.db_name)
def en(db_name):
"""Returns a sql_alchemy engine"""
return sqlalchemy.create_engine('mssql://', creator=Creator(db_name))
這有效:
import sqlalchemy
sqlalchemy.create_engine("DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;").connect()
在該格式中,SQLAlchemy只是忽略連接字符串並將其直接傳遞給pyodbc。
更新:
對不起,我忘記了uri必須是url編碼的,因此,以下工作:
import sqlalchemy
sqlalchemy.create_engine("DRIVER%3D%7BFreeTDS%7D%3BServer%3Dmy.db.server%3BDatabase%3Dmydb%3BUID%3Dmyuser%3BPWD%3Dmypwd%3BTDS_Version%3D8.0%3BPort%3D1433%3B").connect()
在內部“my.db.server:1433”作為連接字符串的一部分傳遞,如SERVER=my.db.server:1433;
。
不幸的是,unixODBC / FreeTDS不接受SERVER位中的端口。 相反,它想要SERVER=my.db.server;PORT=1433;
要將sqlalchemy語法用於連接字符串,必須將端口指定為參數。
sqlalchemy.create_engine("mssql://myuser:mypwd@my.db.server:1433/mydb?driver=FreeTDS& odbc_options='TDS_Version=8.0'").connect()
變為:
sqlalchemy.create_engine("mssql://myuser:mypwd@my.db.server/mydb?driver=FreeTDS&port=1433& odbc_options='TDS_Version=8.0'").connect()
要將各種參數傳遞給connect函數,聽起來像格式字符串可能會做你想要的:
def connect(server, dbname, user, pass):
pyodbc.connect('DRIVER={FreeTDS};Server=%s;Database=%s;UID=%s;PWD=%s;TDS_Version=8.0;Port=1433;' % (server, dbname, user, pass))
然后你會用以下的東西來稱呼它:
connect('myserver', 'mydatabase', 'myuser', 'mypass')
有關格式字符串的更多信息,請訪問: http : //docs.python.org/library/string.html#formatstrings
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.