pysybase.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # sybase/pysybase.py
  2. # Copyright (C) 2010-2017 the SQLAlchemy authors and contributors
  3. # <see AUTHORS file>
  4. #
  5. # This module is part of SQLAlchemy and is released under
  6. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  7. """
  8. .. dialect:: sybase+pysybase
  9. :name: Python-Sybase
  10. :dbapi: Sybase
  11. :connectstring: sybase+pysybase://<username>:<password>@<dsn>/\
  12. [database name]
  13. :url: http://python-sybase.sourceforge.net/
  14. Unicode Support
  15. ---------------
  16. The python-sybase driver does not appear to support non-ASCII strings of any
  17. kind at this time.
  18. """
  19. from sqlalchemy import types as sqltypes, processors
  20. from sqlalchemy.dialects.sybase.base import SybaseDialect, \
  21. SybaseExecutionContext, SybaseSQLCompiler
  22. class _SybNumeric(sqltypes.Numeric):
  23. def result_processor(self, dialect, type_):
  24. if not self.asdecimal:
  25. return processors.to_float
  26. else:
  27. return sqltypes.Numeric.result_processor(self, dialect, type_)
  28. class SybaseExecutionContext_pysybase(SybaseExecutionContext):
  29. def set_ddl_autocommit(self, dbapi_connection, value):
  30. if value:
  31. # call commit() on the Sybase connection directly,
  32. # to avoid any side effects of calling a Connection
  33. # transactional method inside of pre_exec()
  34. dbapi_connection.commit()
  35. def pre_exec(self):
  36. SybaseExecutionContext.pre_exec(self)
  37. for param in self.parameters:
  38. for key in list(param):
  39. param["@" + key] = param[key]
  40. del param[key]
  41. class SybaseSQLCompiler_pysybase(SybaseSQLCompiler):
  42. def bindparam_string(self, name, **kw):
  43. return "@" + name
  44. class SybaseDialect_pysybase(SybaseDialect):
  45. driver = 'pysybase'
  46. execution_ctx_cls = SybaseExecutionContext_pysybase
  47. statement_compiler = SybaseSQLCompiler_pysybase
  48. colspecs = {
  49. sqltypes.Numeric: _SybNumeric,
  50. sqltypes.Float: sqltypes.Float
  51. }
  52. @classmethod
  53. def dbapi(cls):
  54. import Sybase
  55. return Sybase
  56. def create_connect_args(self, url):
  57. opts = url.translate_connect_args(username='user', password='passwd')
  58. return ([opts.pop('host')], opts)
  59. def do_executemany(self, cursor, statement, parameters, context=None):
  60. # calling python-sybase executemany yields:
  61. # TypeError: string too long for buffer
  62. for param in parameters:
  63. cursor.execute(statement, param)
  64. def _get_server_version_info(self, connection):
  65. vers = connection.scalar("select @@version_number")
  66. # i.e. 15500, 15000, 12500 == (15, 5, 0, 0), (15, 0, 0, 0),
  67. # (12, 5, 0, 0)
  68. return (vers / 1000, vers % 1000 / 100, vers % 100 / 10, vers % 10)
  69. def is_disconnect(self, e, connection, cursor):
  70. if isinstance(e, (self.dbapi.OperationalError,
  71. self.dbapi.ProgrammingError)):
  72. msg = str(e)
  73. return ('Unable to complete network request to host' in msg or
  74. 'Invalid connection state' in msg or
  75. 'Invalid cursor state' in msg)
  76. else:
  77. return False
  78. dialect = SybaseDialect_pysybase