SqlAlchemy equivalent of pyodbc connect string using FreeTDS

后端 未结 5 1470
借酒劲吻你
借酒劲吻你 2020-12-08 01:37

The following works:

import pyodbc
pyodbc.connect(\'DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;\')


        
相关标签:
5条回答
  • 2020-12-08 01:39

    To pass various parameters to your connect function, it sounds like format string might do what you want:

    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))
    

    And you would then call it with something like:

    connect('myserver', 'mydatabase', 'myuser', 'mypass')
    

    More info on format strings is here: http://docs.python.org/library/string.html#formatstrings

    0 讨论(0)
  • 2020-12-08 01:42

    I'm still interested in a way to do this in one line within the sqlalchemy create_engine statement, but I found the following workaround detailed here:

    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)
    

    UPDATE: Addresses a concern I raised in my own comment about not being able to pass arguments to the connect string. The following is a general solution if you need to dynamically connect to different databases at runtime. I only pass the database name as a parameter, but additional parameters could easily be used as needed:

    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))
    
    0 讨论(0)
  • 2020-12-08 01:48

    The example by @Singletoned would not work for me with SQLAlchemy 0.7.2. From the SQLAlchemy docs for connecting to 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.

    So to make it work I used:

    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))
    

    This should apply to Sybase as well.

    NOTE: In python 3 the urllib module has been split into parts and renamed. Thus, this line in python 2.7:

    quoted = urllib.quote_plus
    

    has to be changed to this line in python3:

    quoted = urllib.parse.quote_plus
    
    0 讨论(0)
  • 2020-12-08 01:48

    Internally "my.db.server:1433" is passed as part of a connection string like SERVER=my.db.server:1433;.

    Unfortunately unixODBC/FreeTDS won't accept a port in the SERVER bit. Instead it wants SERVER=my.db.server;PORT=1433;

    To use the sqlalchemy syntax for a connection string, you must specify the port as a parameter.

    sqlalchemy.create_engine("mssql://myuser:mypwd@my.db.server:1433/mydb?driver=FreeTDS& odbc_options='TDS_Version=8.0'").connect()
    

    becomes:

    sqlalchemy.create_engine("mssql://myuser:mypwd@my.db.server/mydb?driver=FreeTDS&port=1433& odbc_options='TDS_Version=8.0'").connect()
    
    0 讨论(0)
  • 2020-12-08 02:01

    This works:

    import sqlalchemy
    sqlalchemy.create_engine("DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;").connect()
    

    In that format, SQLAlchemy just ignores the connection string and passes it straight on to pyodbc.

    Update:

    Sorry, I forgot that the uri has to be url-encoded, therefore, the following works:

    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()
    
    0 讨论(0)
提交回复
热议问题