参悟python元类(又称metaclass)系列实战(二)

参悟python元类(又称metaclass)系列实战(二)[Python基础]

写在前面

在上一章节参悟python元类(又称metaclass)系列实战(一)简单介绍了什么是元类、怎么用以及其作用。

本节内容主要为过渡,但同样重要。

有误的地方恳请大神指正下。

ORM

  • 全称“Object Relational Mapping”,即对象-关系映射,具体做法就是

    1. 把一张表映射成一个类
    2. 把表中的每一行数据,映射成一个类的实例

  • 目的是“写代码更简单,不用写SQL语句(但不可能完全取代sql)”

假设mysql(version: 5.5.62)中有如下一张表users

uid

email

passwd

admin

name

birthday

image

created_at

updated_at

created_by

updated_by

is_deleted

101

admin@z417.top

21232f297a57a5a743894a0e4a801fc3

1

管理员

2020-11-03

about:blank

2020-11-03 08:31:32

2020-11-03 08:32:46

101

101

0

102

z417@z417.com

4a80b99f5591cdf5620014d5c7685fc6

0

z417

NULL

about:blank

2020-11-03 09:46:29

2020-11-03 10:32:32

101

103

1

  • 具体的字段描述请阅读下面的建表语句

CREATE TABLE `users` (

`uid` int(11) unsigned NOT NULL AUTO_INCREMENT,

`email` varchar(50) NOT NULL,

`passwd` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT "",

`admin` tinyint(1) unsigned NOT NULL DEFAULT "0" COMMENT "0普通用户,1管理员,2游客",

`name` varchar(50) NOT NULL,

`birthday` DATE COMMENT"用户生日",

`image` varchar(500) NOT NULL DEFAULT "about:blank" COMMENT "头像,base64 encode in file",

`created_at` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00",

`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

`created_by` int(11) unsigned COMMENT "创建人uid",

`updated_by` int(11) unsigned COMMENT "修改人uid",

`is_deleted` tinyint(1) unsigned NOT NULL DEFAULT "0" COMMENT "1代表逻辑删除",

PRIMARY KEY (`uid`),

CONSTRAINT `fk_self_uidxCre` FOREIGN KEY(`created_by`) REFERENCES users(`uid`),

CONSTRAINT `fk_self_uidxUpd` FOREIGN KEY(`updated_by`) REFERENCES users(`uid`),

UNIQUE KEY `emailxDel` (`email`,`is_deleted`),

UNIQUE KEY `namexDel` (`name`,`is_deleted`),

KEY `index_created_at` (`created_at`)

) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

抽象出列的属性

  • 这里我们只关注字段类型、默认值、是否为主键,其余暂不care
  • 基于上一点,抽象出一个类如下
    class Field():

    """映射字段名、字段类型和默认值"""

    def __init__(self, columnType, primaryKey, default):

    self.columnType = columnType

    self.primaryKey = primaryKey

    self.default = default

    def __str__(self):

    """

    该方法在Field的实例被print时调用,这样自定义后,就不会打印内存地址了,

    而是打印‘<类名: columnType>’

    """

    # 这是python3.7及以后新增的写法,等于"<{}: {}>".format(self.__class__.__name__, self.columnType)

    return f"<{self.__class__.__name__}: {self.columnType}>"

  • 对于users表可能需要再细分6种字段,分别如下
    class StrField(Field):

    """映射字符类型,如char和varchar"""

    def __init__(self, primaryKey=False, default=None, ddl="varchar(100)"):

    """

    主键、默认值和类型三要素,在实例化时候可传入参数定制,这里先给了默认值

    """

    super().__init__(ddl, primaryKey, default)

    class BooleanField(Field):

    """映射boolean类型"""

    def __init__(self, default=False):

    """

    mysql布尔类型关键字:boolean

    布尔类型不可能做主键,所以primaryKey写死False

    默认值False

    """

    super().__init__("boolean", False, default)

    class IntegerField(Field):

    """映射整型,如int"""

    def __init__(self, primaryKey=False, default=0, ddl="bigint"):

    """实例化时可通过参数定制3要素"""

    super().__init__(ddl, primaryKey, default)

    class FloatField(Field):

    """映射浮点类型,如float, real"""

    def __init__(self, primaryKey=False, default=0.0, ddl="real"):

    super().__init__(ddl, primaryKey, default)

    class TextField(Field):

    """映射大文本类型,如text"""

    def __init__(self, default=None, ddl="text"):

    """一般不会做主键,所以primaryKey写死False"""

    super().__init__(ddl, False, default)

    class DateTimeField(Field):

    """映射时间类型,如timestamp, date, datetime"""

    def __init__(self, default=None, ddl="timestamp"):

    """一般不会做主键,所以primaryKey写死False"""

    super().__init__(ddl, False, default)

有了上面的内容做铺垫,接下来就是把select,insert,update等sql操作整合到一个类里,下节再赘述

以上是 参悟python元类(又称metaclass)系列实战(二) 的全部内容, 来源链接: utcz.com/z/537771.html

回到顶部