async def save(self, **kwargs): # external save method if self.deleted: raise ModelError( 'That {model_name} has already been deleted!'.format( model_name=self.__class__.__name__)) await self.objects.save(self)
def get_fields(cls): fields = {} cls.attr_names = {} for f_n, field in cls.__dict__.items(): if isinstance(field, Field): field.orm_field_name = f_n if not field.db_column: field.set_field_name(f_n) if not field.table_name: field.table_name = cls.cls_tablename() if isinstance(field, ManyToManyField): field.own_model = cls.cls_tablename() field.table_name = "{my_model}_{foreign_key}".format( my_model=cls.cls_tablename(), foreign_key=field.foreign_key) if not isinstance(field.__class__, AutoField): cls.attr_names.update({f_n: field.db_column}) if hasattr(field, "field_requirement"): if field.field_requirement not in cls.field_requirements: cls.field_requirements.append(field.field_requirement) fields[f_n] = field if len(cls.attr_names) != len(set(cls.attr_names)): raise ModelError( "Models should have unique attribute names and field_name if explicitly edited!" ) return fields
async def set_requirements(self): '''Add to the database the table requirements if needed''' try: for query in self.model.field_requirements: await self.db_manager.request(query) except InsufficientPrivilegeError: raise ModelError( 'Not enought privileges to add the needed requirement in the database' )
def get_model(self, model_name): if len(self.models) == 1: raise AppError('There are no apps declared in the orm') try: model_split = model_name.split('.') if len(model_split) == 2: return self.apps[model_split[0]].models[model_split[1]] elif len(model_split) == 1: return self.models[model_name] else: raise ModelError( 'The string declared should be in format "module.Model" or "Model"' ) except KeyError: raise AppError('The model does not exists')
def validate_kwargs(self, kwargs): '''validate the kwargs on object instantiation only''' attr_errors = [k for k in kwargs.keys() if k not in self.fields.keys()] if attr_errors: err_string = '"{}" is not an attribute for {}' error_list = [ err_string.format(k, self.__class__.__name__) for k in attr_errors ] raise ModelError(error_list) for k, v in kwargs.items(): att_field = getattr(self.__class__, k) att_field.validate(v) if att_field.__class__ is AutoField and v: raise FieldError('Models can not be generated with forced id')
async def save(self, instanced_model): # performs the database save fields, field_data = [], [] for k, data in instanced_model.data.items(): f_class = getattr(instanced_model.__class__, k) field_name = f_class.db_column or k data = f_class.sanitize_data(data) fields.append(field_name) field_data.append(data) for field in instanced_model.fields.keys(): if field not in fields: f_class = getattr(instanced_model.__class__, field) field_name = f_class.db_column or field data = getattr(instanced_model, field) field_has_default = hasattr(instanced_model.fields[field], 'default') default_not_none = instanced_model.fields[ field].default is not None not_auto_field = not isinstance(f_class, AutoField) if data is None and field_has_default and default_not_none and not_auto_field: data = instanced_model.fields[field].default data = f_class.sanitize_data(data) fields.append(field_name) field_data.append(data) db_request = [{ 'action': getattr(instanced_model, instanced_model.orm_pk) and 'db__update' or 'db__insert', 'id_data': '{}={}'.format( instanced_model.db_pk, getattr(instanced_model, instanced_model.orm_pk), ), 'field_names': ', '.join(fields), 'field_values': field_data, 'field_schema': ', '.join( ['${}'.format(value + 1) for value in range(len(field_data))]), 'condition': '{}={}'.format(instanced_model.db_pk, getattr(instanced_model, instanced_model.orm_pk)) }] try: response = await self.db_request(db_request) except UniqueViolationError: raise ModelError('The model violates a unique constraint') self.modelconstructor(response, instanced_model) # now we have to save the m2m relations: m2m_data fields, field_data = [], [] for k, data in instanced_model.m2m_data.items(): # for each of the m2m fields in the model, we have to check # if the table register already exists in the table otherwise # and delete the ones that are not in the list # first get the table_name cls_field = getattr(instanced_model.__class__, k) table_name = cls_field.table_name foreign_column = cls_field.foreign_key model_column = instanced_model.cls_tablename() model_id = getattr(instanced_model, instanced_model.orm_pk) db_request = [{ 'table_name': table_name, 'action': 'db__insert', 'field_names': ', '.join([model_column, foreign_column]), 'field_values': [model_id, data], 'field_schema': ', '.join([ '${}'.format(value + 1) for value in range(len([model_id, data])) ]), }] if isinstance(data, list): for d in data: db_request[0].update({ 'field_values': [model_id, d], 'field_schema': ', '.join([ '${}'.format(value + 1) for value in range(len([model_id, d])) ]) }) await self.db_request(db_request) else: await self.db_request(db_request)