예제 #1
0
파일: db.py 프로젝트: WuAnwenSherry/Grimm
def execute(_execute):
    '''standard SQL API for executing SQL script line'''
    # check SQL connection status
    if session_connection is None or session_connection.open is False:
        e = SQLConnectionError()
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    if isinstance(_execute, bytes):
        _execute.decode('utf8')
    if not isinstance(_execute, str):
        raise SQLValueError('execution', 'invalid executed script')

    cursor = session_connection.cursor()
    try:
        cursor.execute(_execute)
        cursor.close()
        session_connection.commit()
    except pymysql.err.Error as e:
        raise e

    return cursor
예제 #2
0
파일: db.py 프로젝트: WuAnwenSherry/Grimm
def expr_insert(tbl, vals=None, **kwargs):
    '''standard SQL API for database insert operation using expressions'''
    if session_connection is None or session_connection.open is False:
        e = SQLConnectionError()
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    insert_values = insert_columns = ''

    if isinstance(tbl, bytes):
        tbl = tbl.decode('utf8')
    if not isinstance(tbl, (str, tuple, list)):
        e = SQLValueError('expression insert', 'invalid table name')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if isinstance(tbl, (tuple, list)):
        if len(tbl) > 1:
            db_logger.warning('expression insert multiple tables: %s',
                              ','.join(tbl))
        table = str(tbl[0]) if not isinstance(tbl[0], str) else tbl[0].strip()
    else:
        table = tbl.strip('\'" ')
    if not table:
        e = SQLValueError('expression insert', 'null table')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    if vals is not None:
        if not isinstance(vals, (dict, list, tuple)) or len(vals) == 0:
            e = SQLValueError('expression insert', 'invalid values')
            db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode,
                            e.emsg)
            raise e

        if isinstance(vals, dict):
            columns = [k.strip('\'"') for k in vals.keys()]
            insert_columns = f"({','.join(columns)})"
            values = [
                v.decode('utf8') if isinstance(v, bytes) else v
                for v in vals.values()
            ]
        else:
            values = [
                v.decode('utf8') if isinstance(v, bytes) else v for v in vals
            ]
        insert_values = f'{tuple(values)}'
        kwargs = None

    if kwargs is not None:
        columns = [k.strip('\'"') for k in kwargs.keys()]
        insert_columns = f"({','.join(columns)})"
        values = [
            v.decode('utf8') if isinstance(v, bytes) else v
            for v in kwargs.values()
        ]
        insert_values = f'{tuple(values)}'

    # do insert
    if insert_columns:
        _insert = f'insert into {table} {insert_columns} values {insert_values}'
    else:
        _insert = f'insert into {table} values {insert_values}'
    print('expression insert: ', _insert)
    db_logger.info('SQL expression inserting: %s', _insert)
    cursor = session_connection.cursor()
    try:
        result = cursor.execute(_insert)
        cursor.close()
        session_connection.commit()
    except pymysql.err.Error as e:
        db_logger.error('SQL expression insert execution error: (%d, %s)',
                        e.args[0], e.args[1])
        raise e

    return result
예제 #3
0
파일: db.py 프로젝트: WuAnwenSherry/Grimm
def expr_update(tbl, pairs, clauses=None, **kwargs):
    '''standard SQL API for database update operation using expressions'''
    if session_connection is None or session_connection.open is False:
        e = SQLConnectionError()
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    where_clause = ''
    update_exprs = []

    if isinstance(tbl, bytes):
        tbl = tbl.decode('utf8')
    if not isinstance(tbl, (str, tuple, list)):
        e = SQLValueError('expression update', 'invalid table name')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if isinstance(tbl, (tuple, list)):
        if len(tbl) > 1:
            db_logger.warning('expression update multiple tables: %s',
                              ','.join(tbl))
        table = str(tbl[0]) if not isinstance(tbl[0], str) else tbl[0].strip()
    else:
        table = tbl.strip('\'" ')
    if not table:
        e = SQLValueError('expression update', 'null table')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    if not isinstance(pairs, dict) or len(pairs) == 0:
        e = SQLValueError('expression update', 'invalid new pairs')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    # parse clause, including kwargs clause & dictionary clause
    # function arguement clause
    if clauses is None and not kwargs:
        e = SQLValueError('expression update', 'need to specify where clause')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if clauses is not None:
        where_clause = join_exprs_clause(clauses)
        kwargs = None

    # **kwargs arguement clause
    typeinfo = query_tbl_fields_datatype(table, '*')
    if kwargs is not None:
        where_clause = parse_kwargs_clause(tbls=tbl, **kwargs)

    # parse update pairs
    for k, v in pairs.items():
        k = k.strip('\'" ') if isinstance(k, str) else k
        if isinstance(v, bytes):
            v = v.decode('utf8')
        # add quotes for words
        if isinstance(v, str) and v.strip()[0] not in '\'"':
            print('value %s not quoted' % (v))
            if typeinfo[k] in SQL_QUOTED_TYPES:
                v = f"'{v.strip()}'"
            else:
                v = v.strip()

        update_exprs += [f'{k}={v}']
    print('update_exprs:', update_exprs)
    update_pairs = ','.join(update_exprs)

    # do update
    if where_clause:
        _update = f'update {table} set {update_pairs} where {where_clause}'
    else:
        _update = f'update {table} set {update_pairs}'
    print('expression update: ', _update)
    db_logger.info('SQL expression updating: %s', _update)
    cursor = session_connection.cursor()
    try:
        result = cursor.execute(_update)
        cursor.close()
        session_connection.commit()
    except pymysql.err.Error as e:
        db_logger.error('SQL expression update execution error: (%d, %s)',
                        e.args[0], e.args[1])
        raise e

    return result
예제 #4
0
파일: db.py 프로젝트: WuAnwenSherry/Grimm
def expr_query(tbls, fields='*', clauses=None, **kwargs):
    '''standard SQL API for database query operation using expressions'''
    if session_connection is None or session_connection.open is False:
        e = SQLConnectionError()
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    # default expr connector is 'and', expr operator is '=' for **kwargs
    where_clause = ''

    # concatenate target tables
    if isinstance(tbls, bytes):
        tbls = tbls.decode('utf8')
    if not isinstance(tbls, (str, tuple, list)):
        e = SQLValueError('expression query', 'invalid table names')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if isinstance(tbls, (tuple, list)):
        tables = ','.join([
            str(tbl) if not isinstance(tbl, str) else tbl.strip()
            for tbl in tbls
        ])
        table_count = len(tbls)
    else:
        tables = tbls.strip('\'" ')
        table_count = 1
    if not tables:
        e = SQLValueError('expression query', 'null table')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    # special case, no querying * from multiple tables
    if table_count > 1 and fields == '*':
        e = SQLValueError('expression query', 'select * from multiple tables')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    # concatenate query columns
    if isinstance(fields, bytes):
        fields = fields.decode('utf8')
    if not isinstance(fields, (str, tuple, list)):
        e = SQLValueError('expression query', 'invalid field names')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if fields == '*':
        fields = query_tbl_fields(tbls)
        columns = ','.join(fields)
    elif isinstance(fields, str):
        columns = fields.strip('\'" ')
    else:
        fields = [
            str(c) if not isinstance(c, str) else c.strip('\'" ')
            for c in fields
        ]
        columns = ','.join(fields)

    # parse clause, including kwargs clause & dictionary clause
    # function arguement clause
    if clauses is not None:
        where_clause = join_exprs_clause(clauses)
        kwargs = None

    # **kwargs arguement clause
    if kwargs is not None:
        where_clause = parse_kwargs_clause(tbls=tbls, fields=fields, **kwargs)

    # do query
    if where_clause:
        _query = f"select {columns} from {tables} where {where_clause}"
    else:
        _query = f"select {columns} from {tables}"
    print('expression query: ', _query)
    db_logger.info('SQL expression querying: %s', _query)
    cursor = session_connection.cursor()
    try:
        cursor.execute(_query)
        cursor.close()
        session_connection.commit()
    except pymysql.err.Error as e:
        db_logger.error('SQL expression query execution error: (%d, %s)',
                        e.args[0], e.args[1])
        raise e

    # orgnize fetched records
    records = cursor.fetchall()
    row_count = cursor.rowcount
    if row_count == 0:
        db_logger.warning('Empty query record, SQL: %s', _query)
        return None
    elif row_count == 1:
        new_records = [formatter(x) for x in records[0]]
        data = dict(zip(
            (columns, ), new_records)) if isinstance(fields, str) else dict(
                zip(fields, new_records))
        return (data, )
    else:
        new_records = [[formatter(x) for x in row] for row in records]
        data = [
            dict(zip((columns, ), record))
            if isinstance(fields, str) else dict(zip(fields, record))
            for record in new_records
        ]
        return tuple(data)
예제 #5
0
파일: db.py 프로젝트: WuAnwenSherry/Grimm
def query_tbl_fields_datatype(tbl, fields='*'):
    '''query fields\' datatypes of one table, default is all *'''
    if session_connection is None or session_connection.open is False:
        e = SQLConnectionError()
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    if isinstance(tbl, bytes):
        tbl = tbl.decode('utf8')
    if not isinstance(tbl, (str, tuple, list)):
        e = SQLValueError('query fields datatype', 'invalid table name')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if isinstance(tbl, (tuple, list)):
        if len(tbl) > 1:
            db_logger.warning('query multiple tables fields datatype: %s',
                              ','.join(tbl))
        table = str(tbl[0]) if not isinstance(tbl[0], str) else tbl[0].strip()
    else:
        table = tbl.strip('\'" ')
    if not table:
        e = SQLValueError('query fields datatype', 'null table')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e

    if isinstance(fields, bytes):
        fields = fields.decode('utf8')
    if not isinstance(fields, (str, tuple, list)):
        e = SQLValueError('query fields datatype',
                          'invalid query fields names')
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.ecode, e.emsg)
        raise e
    if fields == '*':
        fields = query_tbl_fields(tbl)
        columns = fields
        opcode = 'IN'
    elif isinstance(fields, str):
        fields = fields.strip()
        columns = fields if fields[0] in '\'"' else f"'{fields}'"
        opcode = '='
    else:
        columns = tuple(
            [c.strip('\'"') if isinstance(c, str) else str(c) for c in fields])
        opcode = 'IN'

    _query = f"SELECT `COLUMN_NAME`,`DATA_TYPE` FROM `INFORMATION_SCHEMA`.`COLUMNS` \
                WHERE `TABLE_NAME` = '{table}' AND `COLUMN_NAME` {opcode} {columns}"

    db_logger.info('SQL fields datatype querying: %s', _query)
    cursor = session_connection.cursor()
    try:
        cursor.execute(_query)
        cursor.close()
        session_connection.commit()
    except pymysql.err.Error as e:
        db_logger.error('%s: (%d, %s)', e.__class__.__name__, e.args[0],
                        e.args[1])
        raise e

    records = cursor.fetchall()
    db_fields = [
        str(row[0]) if not isinstance(row[0], str) else row[0]
        for row in records
    ]
    db_typeinfo = [
        str(row[1]) if not isinstance(row[1], str) else row[1]
        for row in records
    ]

    return dict(zip(db_fields, db_typeinfo))