繁体   English   中英

peewee,mysql和自动递增ID

[英]peewee, mysql and auto incrementing id

我在peewee ORM中具有unique=True字段的模型。 我像这样将数据保存到我的MySQL数据库中:

try:
    model.save()
except IntegrityError: # do not save if it's already in db
    pass

但是当peewee试图保存已经存在于db中的数据时,MySQL递增id且id的顺序被破坏了。 如何避免这种行为?

这是我正在尝试保存的模型:

class FeedItem(Model):
    vendor = ForeignKeyField(Vendor, to_field='name')
    url = CharField(unique=True)
    title = CharField()
    pub = DateTimeField()
    rating = IntegerField(default=0)
    img = CharField(default='null')

def construct(self, vendor, url, title):
    self.vendor = vendor
    self.url = url
    self.title = title
    self.pub = datetime.now()
    self.save()

class Meta:
    database = db

我正在保存它:

for article in feedparser.parse(vendor.feed)['items']:
                try:
                    entry = FeedItem()
                    entry.construct(vendor.name, article.link, article.title)
                except IntegrityError:
                    pass

MySQL递增id,并且id顺序被破坏。 如何避免这种行为?

你不知道

数据库生成的标识符不在您的控制范围内。 它是由数据库生成的。 不能保证所有标识符都必须是连续的并且没有间隙,只是它们是唯一的。 有许多事物会导致该序列中没有数字,例如:

  • 一条记录已删除。
  • 尝试插入一条记录,该记录生成了一个ID,但是在生成该ID之后,插入以某种方式失败。
  • 作为未提交的事务的一部分,插入了一条记录。
  • 作为数据库引擎内部优化的一部分,已将一组ID生成到内存中,并且在使用ID之前,该引擎已关闭。
  • 插入了带有显式ID的记录,导致自动递增功能重新调整为新值。

我可能还没有考虑更多。 但是关键是您根本无法控制该值,数据库引擎可以控制。

如果您想控制该值,则不要使用autoincrement 尽管请注意,这还会带来许多其他问题,而您需要解决哪些autoincrement可以为您解决的问题。 或者,您必须切换到GUID而不是整数,这本身可能会导致您需要考虑其他因素。

我不能肯定这是否可行,但是您可以尝试以下方法:

try:
    with database.atomic():
        model.save()
except IntegrityError:
    pass  # Model already exists.

通过包装atomic() ,代码将在事务中执行(或保存点,如果您已经在事务中)。 这可能导致ID序列保持完整。

不过,我同意David的回答,这确实是数据库的详细信息,不应成为您应用程序逻辑的一部分。 如果您需要单调递增的ID,则应该自己实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM