我想存储代码中使用的实体,并避免出现多次。因此,我的想法是使用一种__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__
方法执行后如何运行该方法?
该__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时,或者从内存中删除对象时,值可以并且将被重用,并且您无法控制它下次或完全在另一个过程中将生成什么值。
如果您只想创建具有useragent
和profile
列的唯一组合的行,则需要UniqueConstraint
在table 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] 删除。
我来说两句