python之数据库db模块
来源:互联网 发布:java eclipse下载64位 编辑:程序博客网 时间:2024/06/05 07:23
#!/usr/bin/env python# -*- coding: utf-8 -*-import time, threading, uuid, logging,functoolsclass Dict(dict): def __init__(self, names=(), **kw): super(Dict, self).__init__(**kw) for k, v in zip(names, values): self[k] = v def __getattr__(self, key): try: return self[key] except KeyError: raise AttributeError(r"'dict' object has no attribute'%s' " % key) def __setattr__(self, key, value): self[key] = valuedef next_id(t=None): if t is None:# t = time.time() return '%015d%s000' % (int(t * 1000), uuid.uuid4().hex)def _profiling(start, sql =''): t = time.time() - start if t > 0.1: logging.warning('[PROFILING] [DB] %s: %s' % (t,sql)) else: logging.info('[PROFILING] [DB] %s: %s' %(t, sql))class DEBrror(Exception): passclass MulticolumnsError(DBError): passclass _LasyConnection(object): def __init__(self): self.connection = None def cursor(self): if self.connection is None: connection = engine.connect() logging.info('open connection <%s>...' % hex(id(connection))) self.connection = connection return self.connection.cursor() def commit(self): self.connection.commit() def rollback(self): self.connection.rollback() //??? def cleanup(self): if self.connection: connection = self.connection self.connection = None logging.info('close connection <%s>...' % hex(id(connection))) connection.close()class _Dbctx(threading.local): def __init__(self): self.connection = None self.transactions = 0 def is_init(self): return not self.connection is None def init(self): logging.info('open lazy connection...') self.connection = _LasyConnection() self.transactions = 0 def cleanup(self): self.connection.cleanup() self.connection = None def cursor(self); return self.connection.cursor() _db_ctx = _Dbctx() engine = Noneclass _Engine(object): def __init__(self, connect): self._connect = connect def connect(self): return self._connect() def creat_engine(user, password, database, host = '127.0.0.1', port = 3306, **kw): import mysql.connector global engine if engine is not None: raise DBError('Engine is already initialized.') params = dict(user = user, password = password, databse = database, host = host, port = port) defaults = dict(use_unicode = True, charset = 'utf-8', collation = 'utf8_general_ci', autocommit = False) for k, v in defaults.iteritems(): params[k] = kw.pop(k, v) params.update(kw) params['buffered'] = True engine = _Engine(lambda:mysql.connector.connect(**params)) logging.info('Init mysql engine <%s> ok.' %hex(id(engine))) class _ConnectionCtx(object): def __enter__(self): global _db_ctx self.should_cleanup = False if not _db_ctx.is_init(): _db_ctx.init() self.should_cleanup = True return self def __exit__(self, excvalue, traceback): global _db_ctx if self.should_cleanup: _db_ctx.cleanup() def connection(): return _ConnectionCtx() def with_connection(func): @functools.wraps(func) def __wrapper(*args, **kw): with _ConnectionCtx(): return func(*args, **kw) return __wrapper class _TransactionCtx(object): def __enter__(self): global _db_ctx self.should_close_conn = False if not _db_ctx.is_init() : _db_ctx.init() self.should_close_conn = True _db_ctx.transactions = _db_ctx.transactions +1 logging.info('begin transaction...' if _db_ctx.transactions==1 else 'join current transaction....) return self def __exit__(self, exctype, excvalue, traceback): global _db_ctx _db_ctx.transactions = _db_ctx.transactions - 1 try: if _db_ctx.transactions == 0: if exctype is None: self.commit() else: self.rollback() finally: if self.should_close_conn: _db_ctx.cleanup() def commit(self): global _db_ctx logging.info('commit transaction...') try: _db_ctx.connection.commit() logging.info('commit ok.') except: logging.warning('commit failed.try rollback...') _db_ctx.connection.rollback() logging.warning('rollback ok.') raise def rollback(self): global _db_ctx logging.warning('rollback transaction...') _db_ctx.connection.rollback() logging.info('rollback ok.') def transaction(): return _TransactionCtx() def with_transaction(func): @functools.wraps(func) def _wrapper(*args, **kw): _start = timt.time() with _TransactionCtx(): return func(*args, **kw) _profiling(_start) return _wrapperdef _select(sql, first, *args): global _db_ctx cursor = None sql = sql.replace('?','%s') logging.info('SQL: %s, ARGS: %s' %(sql, args)) try: cursor = _db_ctx.connection.cursor() cursor.execute(sql, args) if cursor.description: names = [x[0] for x in cursor.description] if first: values = cursor.fetchone() if not values: return None return Dict(name, values) return [Dict(name, x) for x in cursor.fetchall()] finally: if cursor: cursor.close() @with_connectiondef select_one(sql, *args): return _select(sql, True, *args) @with_connectiondef select_int(sql, *args): d = _select(sql, True, *args) if len(d)!= 1: raise MulticolumnsError('Expect only one column') return d.values()[0] @with_connectiondef select(sql, *args): return _select(sql, False, *args)@with_connectiondef _update(sql, *args): global _db_ctx cursor = None sql = sql.replace('?', '%s') logging.info('SQL: %s, ARGS: %s' %(sql, args)) try: cursor = _db_ctx.connection.cursor() cursor.execute(sql, args) r = cursor.rowcount if _db_ctx.transactions == 0 : logging.info('auto commit') _db_ctx.connection.commit() return r finally: if cursor: cursor.close() def insert(table, **kw): cils, args = zip(*kw.iteritems()) sql = 'insert into `%s` (%s) values (%s)' % (table, ','.join(['`%s`' % col for col in cols]), ','.join(['?' for i in range(len(cols))])) return _update(sql, *args) def update(sql, *args): return _update(sql, *args) if __name__ == '__main__': logging.basicConfig(level = logging.DEBUG) creat_engine('www-data', 'www-data', 'test') update('drop table if exists user') update('create table user (id int primary key, name text, email text, passwd text, last_modified real)') import doctest doctest.testmod()
0 0
- python之数据库db模块
- Android学习之 关于DB本地数据库模块
- python模块之sqlite数据库
- python模块之sqlite数据库
- python开发数据库之(python DB API)
- Python 数据库客户端 DB-API
- python模块之MySQLdb: 用python连接mysql数据库
- python模块之MySQLdb: 用python连接mysql数据库
- web.py框架之db模块操作
- Python 数据库接口模块
- Python 数据库接口模块
- python 数据库模块
- python 数据库模块
- Python 数据库 sqlite3模块
- python数据库模块
- python数据库模块MySQLdb
- Python数据库接口规范简介 -- DB-API
- python模块系列 (二)之操作NoSQL数据库hbase
- LeetCode---Construct Binary Tree from Inorder and Postorder Traversal
- 自定义UIAlertView第三方类库
- IOS开发 百度地图添加Annotation,并修改图标。
- linux系统原语
- Collection of Important CV Researchers
- python之数据库db模块
- 1041. 考试座位号(15)
- Linux命令集锦
- MYSQL开发性能研究——批量插入的优化措施
- dataguard 中standby有大量gap解决方法
- 1042. 字符统计(20)
- 编译安卓源码问题汇集
- JavaScript刷新页面
- zookeeper订阅与发布实现