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

时间:2019-03-15 13:07:16

标签: python sqlalchemy

我想存储代码中使用的实体,并避免出现多次。因此,我的想法是使用class Model1Serializer(serializers.Serializer): class Meta: model = Model1 fields = '__all__' class Model2Serializer(serializers.Serializer): class Meta: model = Model2 fields = '__all__' 方法来收集类的主要数据,然后使用一种__init__方法来从类对象中计算ID。这是代码:

__post_init__

在此示例中,可以使用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__方法之后立即运行此方法?

1 个答案:

答案 0 :(得分:2)

__post_init__方法特定于dataclasses库,因为__init__类上的dataclass方法是生成的,并且对其进行重写会完全破坏在__init__类中生成该方法的目的。第一名。

另一方面,

SQLAlchemy在基本模型类上提供了declarative_base()实现(使用super().__init__()为您生成)。设置默认值后,您可以通过SQLAlchemy安全地重用该方法。考虑到__init__提供的def __init__(self, useragent, profile): """specify the main information""" id = generate_new_id(self) super().__init__(id=id, useragent=useragent, profile=profile) 方法仅采用关键字参数:

default

如果您需要先等待其他列的更新值(因为它们可能将Python函数定义为super().__init__()),那么您也可以在调用self之后运行函数,并且分配给def __init__(self, useragent, profile): """specify the main information""" super().__init__(useragent=useragent, profile=profile) self.id = generate_new_id(self)

useragent

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

如果您只想创建包含profileclass 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"), ) 列的唯一组合的行,则需要在UniqueConstraint中定义一个table arguments。不要尝试在Python级别上检测唯一性,因为您不能保证另一个进程不会在同一时间进行相同的检查。数据库可以更好地确定您是否有重复值,而不会冒竞争条件的危险:

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

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

type Query {
  product(_id: ID!): Product!
  products: [Product!]!
}