【问题标题】:Flask SQLAlchemy: How to find the primary key value before adding a new object to the session?Flask SQLAlchemy:如何在向会话中添加新对象之前找到主键值?
【发布时间】:2020-07-05 04:49:16
【问题描述】:

我正在使用b64encode 从表中每一行的主键创建一个唯一的引用字符串。这是我在 Flask SQLAlchemy 中的模型:

class Groups(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    ref_id = db.Column(db.String(20), index = True)

    def __init__(self):
        self.ref_id = id_encode(self.id)

但是,传递给id_encode() 函数的self.id 具有“无”值,而不是主键的值。据我所知,只有在提交会话后才能获得新的主键值,或者通过using the flush() method

这是id_encode()的定义:

def id_encode(num):
        bts = base64.b64encode(bytes(str(num), 'utf-8'))
        print(num)
        return bts.decode()

如果有什么方法可以让它工作,或者有什么更好(但简单)的方法来生成唯一参考 ID?我只是不希望普通用户能够通过输入数字 ID 导航到其他组。

【问题讨论】:

  • “生成唯一参考 ID 的方法是什么……(但很简单)?”你考虑过 UUID v4 吗?
  • @IljaEverilä 谢谢!我本来想说 UUID 生成的 ID 太长了,但是我在查找 uuid 后发现了 shortuuid。

标签: python flask sqlalchemy primary-key uniqueidentifier


【解决方案1】:

您可以做的是用类函数替换 « __init __ »。

所以而不是:

class Groups(db.Model):
id = db.Column(db.Integer, primary_key = True)
ref_id = db.Column(db.String(20), index = True)

def __init__(self):
    self.ref_id = id_encode(self.id)

你应该试试:

class Groups(db.Model):
id = db.Column(db.Integer, primary_key = True)
ref_id = db.Column(db.String(20), index = True)

def generate_id(self):
    self.ref_id = base64.b64encode(bytes(str(self.id), 'utf-8'))

那么当你创建一个新的组对象时,只要记住在提交之前使用该函数即可。

group = Groups(id=xxx, arg2=xxx, arg3=xxx etc) 
# omit "id" if you set it to autoincrement
group.generate_id()
db.session.commit()

【讨论】:

  • "just remember to..." 往往是一个吸引虫子的磁铁,因为大多数人很容易忘记事情。您可以通过修改generate_id() 使其作为column default 工作或通过attribute event 设置值来避免此风险。也就是说,在这种特殊情况下,Ilja 的 UUID 建议可能是最好的方法。
  • “那么当你创建一个新的组对象时,只要记住在提交之前使用该函数”与使用__init__没有区别,如果在将对象添加到会话之间没有发生刷新并调用生成器函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2013-09-28
  • 2014-08-09
  • 1970-01-01
相关资源
最近更新 更多