File: db_utils.py

package info (click to toggle)
python-petl 1.7.17-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,224 kB
  • sloc: python: 22,617; makefile: 109; xml: 9
file content (103 lines) | stat: -rw-r--r-- 3,014 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division


import logging


from petl.compat import callable


logger = logging.getLogger(__name__)
debug = logger.debug


def _is_dbapi_connection(dbo):
    return _hasmethod(dbo, 'cursor')


def _is_clikchouse_dbapi_connection(dbo):
    return 'clickhouse_driver' in str(type(dbo))

    
def _is_dbapi_cursor(dbo):
    return _hasmethods(dbo, 'execute', 'executemany', 'fetchone', 'fetchmany',
                       'fetchall')


def _is_sqlalchemy_engine(dbo):
    return (_hasmethods(dbo, 'execute', 'connect', 'raw_connection')
            and _hasprop(dbo, 'driver'))


def _is_sqlalchemy_session(dbo):
    return _hasmethods(dbo, 'execute', 'connection', 'get_bind')


def _is_sqlalchemy_connection(dbo):
    # N.B., this are not completely selective conditions, this test needs
    # to be applied after ruling out DB-API cursor
    return _hasmethod(dbo, 'execute') and _hasprop(dbo, 'connection')


def _hasmethod(o, n):
    return hasattr(o, n) and callable(getattr(o, n))


def _hasmethods(o, *l):
    return all(_hasmethod(o, n) for n in l)


def _hasprop(o, n):
    return hasattr(o, n) and not callable(getattr(o, n))


# default DB quote char per SQL-92
quotechar = '"'


def _quote(s):
    # crude way to sanitise table and field names
    # conform with the SQL-92 standard. See http://stackoverflow.com/a/214344
    return quotechar + s.replace(quotechar, quotechar+quotechar) + quotechar


def _placeholders(connection, names):
    # discover the paramstyle
    if connection is None:
        # default to using question mark
        debug('connection is None, default to using qmark paramstyle')
        placeholders = ', '.join(['?'] * len(names))
    else:
        mod = __import__(connection.__class__.__module__)

        if not hasattr(mod, 'paramstyle'):
            debug('module %r from connection %r has no attribute paramstyle, '
                  'defaulting to qmark', mod, connection)
            # default to using question mark
            placeholders = ', '.join(['?'] * len(names))

        elif mod.paramstyle == 'qmark':
            debug('found paramstyle qmark')
            placeholders = ', '.join(['?'] * len(names))

        elif mod.paramstyle in ('format', 'pyformat'):
            debug('found paramstyle pyformat')
            placeholders = ', '.join(['%s'] * len(names))

        elif mod.paramstyle == 'numeric':
            debug('found paramstyle numeric')
            placeholders = ', '.join([':' + str(i + 1)
                                      for i in range(len(names))])

        elif mod.paramstyle == 'named':
            debug('found paramstyle named')
            placeholders = ', '.join([':%s' % name
                                      for name in names])

        else:
            debug('found unexpected paramstyle %r, defaulting to qmark',
                  mod.paramstyle)
            placeholders = ', '.join(['?'] * len(names))

    return placeholders