def build_stmt(self): stmt = [] if self.allow_null is True or self.allow_null == 1: stmt.append('NULL') elif self.allow_null is False or self.allow_null == 0: stmt.append('NOT NULL') else: raise ValueError('Allow_null value must be True, False, 0 or 1') if self.auto is not None: if self.auto == 'on_create': stmt.append('DEFAULT CURRENT_TIMESTAMP') elif self.auto == 'on_update': stmt.append( 'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP') elif self.default is not None: if not isinstance(self.default, self._py_type): raise ValueError( f'Except default value {self._py_type} now is {self.default}' ) stmt.append(f'DEFAULT {self.default}') elif not self.allow_null: Logger.warning( f'Not to give default value for NOT NULL field {self.name}') stmt.append(f"COMMENT '{self.comment}'") return stmt
def build_stmt(self): """ Build field definition """ stmt = [] if self.allow_null is True or self.allow_null == 1: stmt.append('NULL') elif self.allow_null is False or self.allow_null == 0: stmt.append('NOT NULL') else: raise ValueError('Allow_null value must be True, False, 0 or 1') if self.default is not None: default = self.default if isinstance(self, Float): default = float(default) if not isinstance(default, self._py_type): raise ValueError( f'Except default value {self._py_type} now is {default}') if isinstance(default, str): default = f"'{self.default}'" stmt.append(f'DEFAULT {default}') elif not self.allow_null: Logger.warning( f'Not to give default value for NOT NULL field {self.name}') stmt.append(f"COMMENT '{self.comment}'") return stmt
async def drop_all(self, module): """ A coroutine that drop all the models of a module Args: module: a module that defines several models Return: A list of droped Model name For example: from tests import models await db.drop_all(models) """ self._checker() succeed = [] for key, value in vars(module).items(): if hasattr(value, '__base__') and value.__base__ is self.Model: if await value.exist(): await value.drop() Logger.info( "dropped Model '{model_name}' from db: '{db}'".format( model_name=key, db=self.db_info.info.db.db ) ) succeed.append(key) else: Logger.error( message="drop table '{}' does not exist".format(key) ) return succeed
async def _update(cls, data, where=None): """ do update by where condition """ if not isinstance(data, dict): raise ValueError('Invalid data type') where_format = None if where is not None: if not isinstance(where, (_Where, _Logic)): raise ValueError('Invalid where type {}'.format(type(where))) where_format = where.format_() cls._has_cols_checker(where_format.col) update_fields = list(data.keys()) update_values = [data[f] for f in update_fields] set_clause = ','.join(['='.join([f, '%s']) for f in update_fields]) if where_format: updete_sql = SQL.update_.complete.format( table_name=cls.__meta__.table, kv=set_clause, condition=where_format.where ) update_values.extend(where_format.arg) else: updete_sql = SQL.update_.no_where.format( table_name=cls.__meta__.table, kv=set_clause ) Logger.warning('Dangerous operation: {}'.format(updete_sql)) return await RequestClient().execute(updete_sql, values=update_values)
async def create_all(self, module): """ A coroutine that create all the models of a module Args: module: a module that defines several models Return: A list of created Model name For example: from tests import models await db.create_all(models) """ self._checker() succeed = [] for key, value in vars(module).items(): if hasattr(value, '__base__') and value.__base__ is self.Model: if not await value.exist(): await value.create() Logger.info( "created Model '{table_name}' in db: '{db}'".format( table_name=key, db=self.db_info.info.db.db ) ) succeed.append(key) else: Logger.error("table '{}' already exists".format(key)) return succeed
async def _batch_add(cls, instances): """ batch add instance """ if not isinstance(instances, (list, tuple)): raise ValueError(f'Add illegal type {instances}') cols = list(cls.__table__.field_dict.keys()) cols_copy = cols.copy() for c in cols_copy: c_type = cls.__table__.field_dict[c] if hasattr(c_type, 'auto') and c_type.auto: cols.remove(c) values = [] for inst in instances: values.append(cls._get_add_values(inst, cols)) insert_sql = cls._get_insert_sql(cols) result = await RequestClient().execute( insert_sql, values=values, is_batch=True ) if result.affected != len(values): Logger.error( f'Failed to insert, affected rows: {result.affected}' ) return result
def _get_value(self, key): value = self.__getattr__(key) if value is None: field = self.__table__.field_dict[key] value = (field() if callable(field) else field.default) Logger.info(f'Using default value for {key}: {value}') setattr(self, key, value) return value
async def unbind(cls): """ A coroutine that call `executer.close()` to unbind db""" if cls.executer is not None: await cls.executer.close() cls.executer = None else: Logger.warning('No binding db connection or closed') return True
def qiniu_upload_file(responce): file_name = get_hash(responce.content) store = TempFiles(file_name) store.save(save_pic, responce) try: result_url = save_qiniu(file_name, os.path.dirname(store.filename)) except Exception as e: Logger.error(error=e, task='qiniu_upload_file') result_url = str(responce.url) store.remove() return result_url
def save_to_qiniu_by_url(url): if not is_url(url): return '' new_url = transform_to_http(url) try: response = requests.get(new_url) except ConnectionError as e: Logger.error(error=e, task='save_to_qiniu_by_url') if response.status_code != 200: Logger.error('response status_code: {}'.format(response.status_code), task='save_to_qiniu_by_url') return str(url) return qiniu_upload_file(response)
def build_meta(): meta = {} for arg in TABLE_DEFAULT: if arg == '__table__': table_name = attrs.get(arg, None) if table_name is None: Logger.warning( "Did not give the table name by '__table__', use the model name" ) table_name = name meta[arg.strip('_')] = table_name else: meta[arg.strip('_')] = attrs.get(arg, None) or TABLE_DEFAULT[arg] if arg in attrs.keys(): attrs.pop(arg) return meta
async def _do_add(cls, instance): """ do add a instance data """ cols = list(instance.__dict__.keys()) values = cls._get_add_values(instance, cols) insert_sql = cls._get_insert_sql(cols) result = await RequestClient().execute(insert_sql, values=values) if result.affected != 1: Logger.error( f'Failed to insert, affected rows: {result.affected}' ) return None if cls.__meta__.auto_pk is True: instance._set_value(cls.__table__.pk, result.last_id, is_loader=True) else: result.last_id = instance.__dict__[cls.__table__.pk] return result.last_id
def __init__(self, length, unsigned=False, allow_null=True, default=None, comment='', name=None): super().__init__(allow_null=allow_null, default=default, comment=comment, name=name) if not isinstance(length, (tuple)): raise ValueError('Length type error') self.length = length[0] if len(length) != 2: Logger.warning('Length format error') self.float_length = length[-1] else: self.float_length = length[1] self.unsigned = unsigned
def __init__( self, length, # auto_increase=False, unsigned=False, allow_null=True, primary_key=False, default=None, comment='', name=None): super().__init__(name=name, allow_null=allow_null, default=default, comment=comment, length=length, unsigned=unsigned) self.primary_key = primary_key if self.primary_key is True: if self.allow_null: Logger.warning('Primary_key is not allow null, use default') self.allow_null = False self.default = None
def qiniu_fetch_file(purl): max_retry = 5 if not is_url(purl): Logger.warning(task='qiniu_fetch', message='input url:%s' % purl) return '' purl = transform_to_http(purl) q_auth = qiniu.Auth(ACCESS_KEY, SECRET_KEY) bucket_path = qiniu.BucketManager(q_auth) for n in range(max_retry): ret = bucket_path.fetch(purl, BUCKET_NAME) if ret is None: continue elif isinstance(ret, tuple) and ret[0] is None: continue else: key = ret[0]['key'] url = DOMAIN + str(key) obj = urlparse.urlparse(url) return obj.geturl() else: Logger.error(task='qiniu_fetch', message='max retry exceed') return purl
async def batch_drop(self, *models): """ A coroutine that batch drop same model. Args: models: one or more models Return: A list of droped table name For example: from tests.models import User, Order await db.batch_drop(User, Order) """ self._checker() succeed = [] if not models: Logger.warning("parameter 'models' is empty, 'batch_drop' nothing to do") return succeed for model in models: if not issubclass(model, self.Model): raise ValueError( 'drop model type must be {}, get {}'.format(self.Model, model) ) if await model.exist(): await model.drop() Logger.info( "dropped table '{table_name}' from db: '{db}'".format( table_name=model.__meta__.table, db=self.db_info.info.db.db ) ) succeed.append(model.__meta__.table) else: Logger.error( message="drop table '{}' does not exist".format(model.__meta__.table) ) return succeed