peewee,mysql和auto递增id

时间:2015-06-18 13:14:58

标签: python mysql peewee

我在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

2 个答案:

答案 0 :(得分:2)

  

MySQL增加id和id顺序被破坏。如何避免这种行为?

你没有。

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

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

我可能还有更多不考虑。但关键是你根本就没有控制那个值,数据库引擎就是这样。

如果您想控制该值,请不要使用autoincrement。虽然要注意这会带来一系列其他问题,您需要解决autoincrement为您解决的问题。或者您必须切换到GUID而不是整数,这本身可能会导致您需要考虑的其他注意事项。

答案 1 :(得分:0)

如果这种方法有效,我会不肯定,但你可以尝试以下方法:

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

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

我同意David的回答,但这确实是一个数据库细节,不应该是你的应用程序逻辑的一部分。如果你需要单调递增ID,你应该自己实现。