python - 使模型的第一个实例在 SQLAlchemy 中具有唯一字段
问题描述
我有一个带有User
模型的 Flask + SQLAlchemy 应用程序。我想强制执行此业务逻辑:User
在应用程序中创建的第一个应该是管理员(即具有字段is_admin=True
),但所有其他用户默认情况下不应是管理员。
该模型看起来像这样(简化):
class User(db.Model):
__tablename__ = "users"
user_id = Column(Integer, primary_key=True)
username = Column(UnicodeText, unique=True, nullable=False)
email = Column(UnicodeText, unique=True, nullable=False)
password = Column(UnicodeText, nullable=True)
is_admin = Column(Boolean(), default=False)
我希望这个测试用例成功:
first = User(username="foo", email="foo@foo.com", password="foobarbaz123")
second = User(username="bar", email="bar@bar.com", password="foobarbaz123")
db.session.add_all([first, second])
db.session.commit()
assert first.is_admin
assert not second.is_admin
我尝试了几种方法:
- 将此业务逻辑放在 API 路由本身中。这样做的主要缺点是它没有集成在模型层中,因此很容易绕过,并且您必须在多个地方维护此功能。
- 将此逻辑放入模型构造函数中,例如
这是行不通的,因为我们不能假设我们随时都可以访问数据库会话。比如在构建测试数据的时候,会涉及到当数据处于不稳定状态的时候打数据库。def __init__(self): user_count = db.session.query(User).count() if user_count == 0: self.is_admin = True
- 将此逻辑放入
after_insert
事件中,例如
然而,这并没有通过测试用例,因为它似乎是异步更新模型。@event.listens_for(User, 'after_insert') def receive_after_insert(mapper, connection, target): user_count = db.session.query(User).count() if user_count == 0: target.is_admin = True
这个业务逻辑如何实现?
解决方案
推荐阅读
- amp-html - 如何处理表单提交后返回的数据
- c - C 中的 Json 解析器 | 内存访问错误(内存转储) - 错误
- ruby-on-rails - 使用 form_tag 传输参数
- android - 我需要使用位图图像,但我不知道如何
- c# - 返回一个重复多次的字符串
- scrapy - “https://www.mywebsite.com.sg”的 Scrapy 视图和 requests.get 差异
- java - toArray 与预先确定的数组
- bigdata - 纱线上的 Oracle PGX - WebService 上的 404
- python - 使用 Python 进行梯度提升 - 一般问题
- android - 删除 actionBar 使我的应用程序崩溃(它说不幸的是,应用程序已停止)