27

次の作品:

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)')なしなし

誰かが私を正しい方向に向けてくれませんか?特定の接続文字列をpyodbcに渡すようにsqlalchemyに簡単に指示する方法はありますか?

注意:このDSNを使用しないようにします。

4

5 に答える 5

43

@Singletonedによる例は、SQLAlchemy0.7.2では機能しません。SQL Serverに接続するためのSQLAlchemyドキュメントから:

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モジュールがパーツに分割され、名前が変更されました。したがって、Python2.7のこの行は次のとおりです。

quoted = urllib.quote_plus

python3では次の行に変更する必要があります。

quoted = urllib.parse.quote_plus
于 2011-09-13T09:27:09.810 に答える
24

私はまだsqlalchemycreate_engineステートメント内の1行でこれを行う方法に興味がありますが、ここで詳細に説明されている次の回避策を見つけました:

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))
于 2010-12-20T20:43:34.393 に答える
5

これは機能します:

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()
于 2011-02-26T21:41:36.477 に答える
5

内部的には、「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()
于 2013-10-19T19:08:37.577 に答える
0

さまざまなパラメータを接続関数に渡すために、フォーマット文字列があなたが望むことをするかもしれないように聞こえます:

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

于 2010-12-22T01:44:07.017 に答える