Patch is attached.
Thanks!

> On Wed, Sep 30, 2009 at 5:51 PM, mdipierro <[email protected]> wrote:
>>
>> Yes. If you send me a patch to do this I will take it.
>> Thank you for reporting the issue.
>>
>> On Sep 30, 2:38 pm, Dmitri Zagidulin <[email protected]> wrote:
>>> I have a web2py app (running on Ubuntu Linux) that has to connect to a
>>> MS SQL Server.
>>> I installed pyodbc, and the FreeTDS ODBC driver.
>>> I defined a driver in odbcinst.ini, etc, etc. And could now connect
>>> from the command line, via isql, to the remote database.
>>>
>>> In web2py, the following connection string:
>>>
>>> db = SQLDB('mssql://myuser:[email protected]:PPP/mydatabase)   #
>>> (PPP being the port number)
>>>
>>> did not work. I traced the matter down to gluon/sql.py lines 833-836:
>>> the engine being created did not seem to be actually using the port
>>> number that was passed in via the connection string.
>>> The port is parsed via regex on line 827, but then is not actually
>>> used in creating the pyodbc connection.
>>>
>>> Also, the engine was assuming that the ODBC driver was named 'SQL
>>> Server' (mine was named 'FreeTDS').
>>>
>>> To make it work temporarily, I ended up commenting out
>>> #self._pool_connection(lambda : pyodbc.connect(cnxn))
>>>
>>> and replacing it with:
>>> self._pool_connection(lambda : pyodbc.connect
>>> ('SERVER=xxx.x.x.x;PORT=PPP;DATABASE=mydatabase;UID=myuser;PWD=mypassword;DRIVER=
>>> {FreeTDS}'))
>>> (which basically hardcodes my connection and bypasses the connection
>>> string in any models - not great).
>>>
>>> So, my question is, what's the right way to fix this? Can you extend
>>> the connection string syntax so that we can pass in the driver name,
>>> and also use the port that is passed in?
>>> (For example, SQLAlchemy allows other arguments in the connect string,
>>> like mssql:// ... /mydatabase?driver={FreeTDS} )
>> >>
>>
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---

--- ref_web2py/web2py/gluon/sql.py      2009-09-28 10:52:38.000000000 -0400
+++ web2py/gluon/sql_mssqlfix.py        2009-10-01 16:45:13.000000000 -0400
@@ -807,7 +807,7 @@
                 cnxn = 'DSN=%s' % dsn
             else:
                 m = \
-                    
re.compile('^(?P<user>[^:@]+)(\:(?P<passwd>[...@]*))?@(?P<host>[^\:/]+)(\:(?P<port>[0-9]+))?/(?P<db>.+)$'
+                    
re.compile('^(?P<user>[^:@]+)(\:(?P<passwd>[...@]*))?@(?P<host>[^\:/]+)(\:(?P<port>[0-9]+))?/(?P<db>[^\?]+)(\?(?P<urlargs>.*))?$'
                                ).match(self._uri[skip:])
                 if not m:
                     raise SyntaxError, \
@@ -828,11 +828,34 @@
                 if not port:
                     port = '1433'
 
+                # Parse the optional url name-value arg pairs after the '?' 
(in the form of arg1=value1&arg2=value2&...)
+                argsdict = { 'DRIVER':'{SQL Server}' } # Default values 
(drivers like FreeTDS insist on uppercase parameter keys)
+                urlargs = m.group('urlargs')
+                if urlargs:
+                    try:
+                        argpattern = 
re.compile('(?P<argkey>[^=]+)=(?P<argvalue>[^&]*)')
+                        # Build a dictionary of of the url args
+                        for argmatch in argpattern.finditer(urlargs):
+                            argsdict[str(argmatch.group('argkey')).upper()] = 
argmatch.group('argvalue')
+
+                        # Render the argument dictionary into a string to be 
appended to the connection string
+                        urlargslist = []
+                        for ak, av in argsdict.items():
+                            urlargslist.append('%s=%s' % (ak, av))
+                        urlargs = ';'.join(urlargslist)
+                        if urlargs:
+                            urlargs = ';%s' % urlargs
+                    except:
+                        raise SyntaxError, \
+                            "Invalid arguments in URI string in SQLDB: %s" % 
self._uri
+                else:
+                    urlargs = ''
+
                 # Driver={SQL 
Server};description=web2py;server=A64X2;uid=web2py;database=web2py_test;network=DBMSLPCN
 
                 cnxn = \
-                    'Driver={SQL Server};server=%s;database=%s;uid=%s;pwd=%s'\
-                     % (host, db, user, passwd)
+                    'SERVER=%s;PORT=%s;DATABASE=%s;UID=%s;PWD=%s%s'\
+                     % (host, port, db, user, passwd, urlargs)
             self._pool_connection(lambda : pyodbc.connect(cnxn))
             self._cursor = self._connection.cursor()
             if self._uri[:8] == 'mssql://':

Reply via email to