如何在普通类中使用等效于__post_init__方法的方法?

忍者

我想存储代码中使用的实体,并避免出现多次。因此,我的想法是使用一种__init__方法收集类的主要数据,然后使用一种__post_init__方法从类对象中计算ID。这是代码:

class Worker(Base):
    __tablename__='worker'
    id = Column(Integer,primary_key=True)
    profile=Column(String(100),nullable=False)
    useragent=Column(String(100),nullable=False)
    def __init__(self,useragent,profile):
        """ specify the main information"""
        print('init')
        self.profile= profile
        self.useragent=useragent
    def __post_init__(self):
        """ compute an id based on self, the worker"""
        self.id=id(self)
        print('dans post init')

在本示例中,__init__可以使用方法,但是它不会__post_init__像我们对数据类所期望的那样运行该方法。

__init__方法执行后如何运行该方法?

马丁·彼得斯(Martijn Pieters)

__post_init__方法是特定于dataclasses库的,因为生成__init__dataclass方法,并且对其进行覆盖会完全破坏首先生成它的目的。

另一方面,SQLAlchemy__init__在基本模型类(使用为您生成declarative_base()提供了一个实现设置默认值后,您可以通过自己安全地重用该方法super().__init__()考虑到SQLAlchemy-provided__init__方法仅采用关键字参数:

def __init__(self, useragent, profile):
    """specify the main information"""
    id = generate_new_id(self)
    super().__init__(id=id, useragent=useragent, profile=profile)

如果您需要先等待其他列的更新值(因为它们可能将Python函数定义为default),那么您也可以在调用后运行函数super().__init__(),而只需将其赋给self

def __init__(self, useragent, profile):
    """specify the main information"""
    super().__init__(useragent=useragent, profile=profile)
    self.id = generate_new_id(self)

注意:您不想使用内置id()函数为SQL插入的数据生成id,因此不能保证该函数返回的值是唯一的它们仅对所有活动Python对象的集合唯一,并且仅在当前进程中才是唯一的。下次运行Python时,或者从内存中删除对象时,值可以并且将被重用,并且您无法控制它下次或完全在另一个过程中将生成什么值。

如果您只想创建具有useragentprofile列的唯一组合的行,则需要UniqueConstrainttable arguments中定义a 不要尝试在Python级别上检测唯一性,因为您不能保证另一个进程不会在同一时间进行相同的检查。数据库可以更好地确定您是否具有重复值,而不会冒竞争条件的危险:

class Worker(Base):
    __tablename__='worker'
    id = Column(Integer, primary_key=True, autoincrement=True)
    profile = Column(String(100), nullable=False)
    useragent = Column(String(100), nullable=False)

    __table_args__ = (
        UniqueConstraint("profile", "useragent"),
    )

或者您可以根据这两列使用复合主键;主键(复合键或其他键)必须始终是唯一的:

class Worker(Base):
    __tablename__='worker'
    profile = Column(String(100), primary_key=True, nullable=False)
    useragent = Column(String(100), primary_key=True, nullable=False)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章