ORM模型定义如何将列属性绑定到实际列?

2024-05-18 10:53:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图理解ORMs如何能够通过class属性解析表列,而不显式地提供表名和列名

from orm import Column

class Car(Model):
    id = Column()

然后,查询可以执行以下操作:

Car.select().where(Car.id == 7)

我知道Column为__eq__操作符定义了一个方法,但是Column实例怎么知道它引用的是类Car和属性id(假设默认情况下它们用于表名和列名)

通过深入了解ORM libs的工作原理,我学到了很多关于python的知识


Tags: 方法fromimportidmodel属性定义orm
1条回答
网友
1楼 · 发布于 2024-05-18 10:53:22

在SqlAlchemy和DJango ORM中,基类(Model)与执行内省的元类或工厂方法(如__new__)相关联

下面是如何使用函数进行复制(更简单的解决方案):

class Model():
    pass


class Column():
    def __init__(self, name=None):
        self.name = name


def setup_class(cls):
    for name, value in cls.__dict__.items():
        if isinstance(value, Column):
            attr = getattr(cls, name)
            attr.name = attr.name or name

这个setup_class函数内省cls类并设置name属性(如果它是空的或None),例如:

class Car(Model):
    id = Column()


from pprint import pprint
pprint(Car.id.name)
# -> None

setup_class(Car)
pprint(Car.id.name)
# -> 'id'

编辑

使用元类的实现示例:

class Column():
    def __init__(self, name=None):
        self.name = name


class MyMeta(type):
    def __new__(cls, name, bases, attrs):
        for name, col in attrs.items():
            if isinstance(col, Column):
                col.name = col.name or name
        return super(MyMeta, cls).__new__(cls, name, bases, attrs)


class Model(metaclass=MyMeta):
    pass


class Car(Model):
    id = Column()


import pprint
pprint.pprint(Car.id.name)
# -> 'id'

当然,这还不够。你必须明白Columndescriptor。此描述符用于构建SQL查询

相关问题 更多 >