Metaclass implementation ORM
ORM is the core idea of Django, "Object Relational Mapping", that is, Object Relational Mapping, which is used to simplify SQL operations, encapsulate database operations into classes, map table names into classes, map fields into properties, and map rows (data) into instances.
class ModelMetaclass(type): def __new__(cls, name, bases, attrs): mappings = dict() # Determine whether to save for k, v in attrs.items(): # Determine whether it is an instance object of the specified StringField or IntegerField if isinstance(v, tuple): print('Found mapping: %s ==> %s' % (k, v)) mappings[k] = v # Delete these properties that are already stored in the dictionary for k in mappings.keys(): attrs.pop(k) # Add the previous uid/name/email/password and the corresponding object reference and class name attrs['__mappings__'] = mappings # Save mapping between attributes and columns attrs['__table__'] = name # Assume that the table name and class name are the same return type.__new__(cls, name, bases, attrs) class User(metaclass=ModelMetaclass): uid = ('uid', "int unsigned") name = ('username', "varchar(30)") email = ('email', "varchar(30)") password = ('password', "varchar(30)") # When a metaclass is specified, the above class properties are not stored in the class, but in the dictionary specified by the mappings property # There are # __mappings__ = { # "uid": ('uid', "int unsigned") # "name": ('username', "varchar(30)") # "email": ('email', "varchar(30)") # "password": ('password', "varchar(30)") # } # __table__ = "User" def __init__(self, **kwargs): for name, value in kwargs.items(): setattr(self, name, value) def save(self): fields = [] args = [] for k, v in self.__mappings__.items(): fields.append(v[0]) args.append(getattr(self, k, None)) args_temp = list() for temp in args: # Judge in if it is a number type if isinstance(temp, int): args_temp.append(str(temp)) elif isinstance(temp, str): args_temp.append("""'%s'""" % temp) sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(args_temp)) print('SQL: %s' % sql) u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd') # print(u.__dict__) u.save()
Note:
- Setattr (object, property, property value) sets the value of the property in the object
- Getattr (object, property [, default]) reads the value of the property from the object. You can set the default value, or read the default value if it does not exist.