I know that kinterbasdb does not support python3, but there is an alternative 
driver fdb which does. This is the driver recommended by the firebird project.

<http://pypi.python.org/pypi/fdb/>


I copied the kinterbasdb driver in sqlalchemy to a new file fdb.py and made 
some minimal changes, mostly string replacements .

It works for me with python2.

I then tried it on a different box which has both py2 and py3.

In this case I get a syntax error when calling  get_pk_constraint() whereby 
connection.execute reports too many parameters.

  File "/usr/lib/python3.2/site-packages/sqlalchemy/dialects/firebird/base.py", 
line 487, in get_pk_constraint
    c = connection.execute(keyqry, ["PRIMARY KEY", tablename])
  File "/usr/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 
1453, in execute
    params)
  File "/usr/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 
1630, in _execute_text
    statement, parameters
  File "/usr/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 
1700, in _execute_context
    context)
  File "/usr/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 
1846, in _handle_dbapi_exception
    from e
sqlalchemy.exc.ProgrammingError: (ProgrammingError) Statement parameter 
sequence contains 11 parameters, but only 10 are allowed '\n        SELECT 
se.rdb$field_name AS fname\n        FROM rdb$relation_constraints rc\n          
   
JOIN rdb$index_segments se ON rc.rdb$index_name=se.rdb$index_name\n        
WHERE rc.rdb$constraint_type=? AND rc.rdb$relation_name=?\n        ' [('P', 
'R', 'I', 'M', 'A', 'R', 'Y', ' ', 'K', 'E', 'Y'),
 ('A', 'C', 'C','O','U','N','T')]



I have been testing using the latest checkouts of firebird 2.5 and 3.0

My patches are attached.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

--- kinterbasdb.py	2012-06-08 11:13:52.000000000 +0200
+++ fdb.py	2012-06-08 11:13:52.000000000 +0200
@@ -1,5 +1,5 @@
-# firebird/kinterbasdb.py
-# Copyright (C) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
+# firebird/fdb.py
+# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
 #
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
@@ -10,8 +10,17 @@
 
 The connection URL is of the form
 ``firebird[+kinterbasdb]://user:password@host:port/path/to/db[?key=value&key=value...]``.
+or
+``firebird[+fdb]://user:password@host:port/path/to/db[?key=value&key=value...]``.
 
-Kinterbasedb backend specific keyword arguments are:
+
+
+An alternative interface, also from the Firebird project is fdb.py. This is currently being 
+enhanced to provide Python3 support as well.
+Fdb claims to be mostly compatible with Kinterbasedb.
+
+
+Kinterbasedb/fdb backend specific keyword arguments are:
 
 * type_conv - select the kind of mapping done on the types: by default
   SQLAlchemy uses 200 with Unicode, datetime and decimal support (see
@@ -22,10 +31,10 @@
 
 * enable_rowcount - True by default, setting this to False disables 
   the usage of "cursor.rowcount" with the 
-  Kinterbasdb dialect, which SQLAlchemy ordinarily calls upon automatically
+  fdb dialect, which SQLAlchemy ordinarily calls upon automatically
   after any UPDATE or DELETE statement.   When disabled, SQLAlchemy's 
   ResultProxy will return -1 for result.rowcount.   The rationale here is 
-  that Kinterbasdb requires a second round trip to the database when 
+  that fdb requires a second round trip to the database when 
   .rowcount is called -  since SQLA's resultproxy automatically closes 
   the cursor after a non-result-returning statement, rowcount must be 
   called, if at all, before the result object is returned.   Additionally,
@@ -39,6 +48,7 @@
       r = conn.execute(stmt)
       print r.rowcount
 
+__ http://pypi.python.org/pypi/fdb
 __ http://sourceforge.net/projects/kinterbasdb
 __ http://firebirdsql.org/index.php?op=devel&sub=python
 __ http://kinterbasdb.sourceforge.net/dist_docs/usage.html#adv_param_conv_dynamic_type_translation
@@ -52,7 +62,7 @@
 from re import match
 
 
-class _FBNumeric_kinterbasdb(sqltypes.Numeric):
+class _FBNumeric_fdb(sqltypes.Numeric):
     def bind_processor(self, dialect):
         def process(value):
             if isinstance(value, decimal.Decimal):
@@ -61,7 +71,7 @@
                 return value
         return process
 
-class FBExecutionContext_kinterbasdb(FBExecutionContext):
+class FBExecutionContext_fdb(FBExecutionContext):
     @property
     def rowcount(self):
         if self.execution_options.get('enable_rowcount', 
@@ -70,34 +80,35 @@
         else:
             return -1
 
-class FBDialect_kinterbasdb(FBDialect):
-    driver = 'kinterbasdb'
+class FBDialect_fdb(FBDialect):
+    driver = 'fdb'
     supports_sane_rowcount = False
     supports_sane_multi_rowcount = False
-    execution_ctx_cls = FBExecutionContext_kinterbasdb
+    execution_ctx_cls = FBExecutionContext_fdb
 
     supports_native_decimal = True
 
     colspecs = util.update_copy(
         FBDialect.colspecs,
         {
-            sqltypes.Numeric:_FBNumeric_kinterbasdb,
+            sqltypes.Numeric:_FBNumeric_fdb,
         }
 
     )
 
     def __init__(self, type_conv=200, concurrency_level=1,
-                            enable_rowcount=True, **kwargs):
-        super(FBDialect_kinterbasdb, self).__init__(**kwargs)
+                            enable_rowcount=True, charset='UTF8', **kwargs):
+        super(FBDialect_fdb, self).__init__(**kwargs)
         self.enable_rowcount = enable_rowcount
         self.type_conv = type_conv
         self.concurrency_level = concurrency_level
+        self.charset = charset
         if enable_rowcount:
             self.supports_sane_rowcount = True
 
     @classmethod
     def dbapi(cls):
-        k = __import__('kinterbasdb')
+        k = __import__('fdb')
         return k
 
     def create_connect_args(self, url):
@@ -113,15 +124,6 @@
         concurrency_level = opts.pop('concurrency_level',
                                     self.concurrency_level)
 
-        if self.dbapi is not None:
-            initialized = getattr(self.dbapi, 'initialized', None)
-            if initialized is None:
-                # CVS rev 1.96 changed the name of the attribute:
-                # http://kinterbasdb.cvs.sourceforge.net/viewvc/kinterbasdb/Kinterbasdb-3.0/__init__.py?r1=1.95&r2=1.96
-                initialized = getattr(self.dbapi, '_initialized', False)
-            if not initialized:
-                self.dbapi.init(type_conv=type_conv,
-                                    concurrency_level=concurrency_level)
         return ([], opts)
 
     def _get_server_version_info(self, connection):
@@ -137,8 +139,10 @@
         # where the first version is a fake one resembling the old
         # Interbase signature. 
 
+        isc_info_firebird_version = 103
+
         fbconn = connection.connection
-        version = fbconn.server_version
+        version = fbconn.db_info(isc_info_firebird_version)
 
         return self._parse_version_info(version)
 
@@ -164,4 +168,4 @@
         else:
             return False
 
-dialect = FBDialect_kinterbasdb
+dialect = FBDialect_fdb

Reply via email to