美文网首页python技术专栏
python元类OCR创建数据库

python元类OCR创建数据库

作者: huxt | 来源:发表于2019-08-08 11:27 被阅读0次

    1.元类编程架构

    # 需求

    import numbers

    class Field:

        pass

    class IntField(Field):

        # 数据描述符

        def __init__(self, db_column, min_value=None, max_value=None):

            self._value = None

            self.min_value = min_value

            self.max_value = max_value

            self.db_column = db_column

            if min_value is not None:

                if not isinstance(min_value, numbers.Integral):

                    raise ValueError("min_value must be int")

                elif min_value < 0:

                    raise ValueError("min_value must be positive int")

            if max_value is not None:

                if not isinstance(max_value, numbers.Integral):

                    raise ValueError("max_value must be int")

                elif max_value < 0:

                    raise ValueError("max_value must be positive int")

            if min_value is not None and max_value is not None:

                if min_value > max_value:

                    raise ValueError("min_value must be smaller than max_value")

        def __get__(self, instance, owner):

            return self._value

        def __set__(self, instance, value):

            if not isinstance(value, numbers.Integral):

                raise ValueError("int value need")

            if value < self.min_value or value > self.max_value:

                raise ValueError("value must between min_value and max_value")

            self._value = value

    class CharField(Field):

        def __init__(self, db_column, max_length=None):

            self._value = None

            self.db_column = db_column

            if max_length is None:

                raise ValueError("you must spcify max_lenth for charfiled")

            self.max_length = max_length

        def __get__(self, instance, owner):

            return self._value

        def __set__(self, instance, value):

            if not isinstance(value, str):

                raise ValueError("string value need")

            if len(value) > self.max_length:

                raise ValueError("value len excess len of max_length")

            self._value = value

    class ModelMetaClass(type):

        def __new__(cls, name, bases, attrs, **kwargs):

            if name == "BaseModel":

                return super().__new__(cls, name, bases, attrs, **kwargs)

            fields = {}

            for key, value in attrs.items():

                if isinstance(value, Field):

                    fields[key] = value

            attrs_meta = attrs.get("Meta", None)

            _meta = {}

            db_table = name.lower()

            if attrs_meta is not None:

                table = getattr(attrs_meta, "db_table", None)

                if table is not None:

                    db_table = table

            _meta["db_table"] = db_table

            attrs["_meta"] = _meta

            attrs["fields"] = fields

            del attrs["Meta"]

            return super().__new__(cls, name, bases, attrs, **kwargs)

    class BaseModel(metaclass=ModelMetaClass):

        def __init__(self, *args, **kwargs):

            for key, value in kwargs.items():

                setattr(self, key, value)

            return super().__init__()

        def save(self):

            fields = []

            values = []

            for key, value in self.fields.items():

                db_column = value.db_column

                if db_column is None:

                    db_column = key.lower()

                fields.append(db_column)

                value = getattr(self, key)

                values.append(str(value))

            sql = "insert {db_table}({fields}) value({values})".format(db_table=self._meta["db_table"],

                                                                      fields=",".join(fields), values=",".join(values))

            pass

    class User(BaseModel):

        name = CharField(db_column="name", max_length=10)

        age = IntField(db_column="age", min_value=1, max_value=100)

        class Meta:

            db_table = "user"

    if __name__ == "__main__":

        user = User(name="bobby", age=28)

        # user.name = "bobby"

        # user.age = 28

        user.save()

    相关文章

      网友评论

        本文标题:python元类OCR创建数据库

        本文链接:https://www.haomeiwen.com/subject/twytjctx.html