python - SqlAlchemy 为每个新组合自动增加复合键
问题描述
我有一个场景来迭代session_number
相关的列user_name
。如果用户在我将迭代最后一个会话之前创建了一个会话,session_number
但如果用户第一次创建会话session_number
应该从 1 开始。我试图在下面进行说明。现在我通过使用逻辑来处理这个问题,但尝试在 SqlAlchemy 中找到更优雅的方法来做到这一点。
id - user_name - session_number
1 user_1 1
2 user_1 2
3 user_2 1
4 user_1 3
5 user_2 2
这是我的表格的python代码。我的数据库是 PostgreSQL,我正在使用 alembic 来升级表。现在它继续迭代上session_number
不管user_name
。
class UserSessions(db.Model):
__tablename__ = 'user_sessions'
id = db.Column(db.Integer, primary_key=True, unique=True)
username = db.Column(db.String, nullable=False)
session_number = db.Column(db.Integer, Sequence('session_number_seq', start=0, increment=1))
created_at = db.Column(db.DateTime)
last_edit = db.Column(db.DateTime)
__table_args__ = (
db.UniqueConstraint('username', 'session_number', name='_username_session_number_idx_'),
)
我已经在互联网上搜索过这种情况,但那些不是我的问题。是否可以通过 SqlAlchemy/PostgreSQL 操作来实现这一点?
解决方案
首先,我不知道通过使用 SqlAlchemy 或 Postgresql 或两者的组合来解决这种情况的任何“纯”解决方案。
虽然它可能不是您正在寻找的解决方案,但我希望它能给您一些想法。
如果您想计算session_number
整个表而不存储它,我将使用以下查询或其变体:
def get_user_sessions_with_rank():
expr = (
db.func.rank()
.over(partition_by=UserSessions.username, order_by=[UserSessions.id])
.label("session_number")
)
subq = db.session.query(UserSessions.id, expr).subquery("subq")
q = (
db.session.query(UserSessions, subq.c.session_number)
.join(subq, UserSessions.id == subq.c.id)
.order_by(UserSessions.id)
)
return q.all()
或者,我实际上会column_property
在模型中添加一个,为每个UserSessions
. 它的计算效率不高,但对于按特定用户过滤的查询,它应该足够好:
class UserSessions(db.Model):
__tablename__ = "user_sessions"
id = db.Column(db.Integer, primary_key=True, unique=True)
username = db.Column(db.String, nullable=False)
created_at = db.Column(db.DateTime)
last_edit = db.Column(db.DateTime)
# must define this outside of the model definition because of need for aliased
US2 = db.aliased(UserSessions)
UserSessions.session_number = db.column_property(
db.select(db.func.count(US2.id))
.where(US2.username == UserSessions.username)
.where(US2.id <= UserSessions.id)
.scalar_subquery()
)
在这种情况下,当您查询 时UserSessions
,session_number
将从数据库中获取 ,同时None
用于新创建的实例。
推荐阅读
- javascript - 在反应中访问dom元素
- python - Django admin 反向外键关系
- azure-devops - 指定的 Swagger 版本未知。Azure APIM ARM 模板
- javascript - 更新对象属性具有特定值的数组
- python - Pandas:根据除一行之外的其他多级列按组对最内列进行排序
- c# - 值未从 service-proxies.ts 文件传递到 Appservices.cs
- python - 如何为特定领域的表征学习任务训练一个 BERT 模型?
- reactjs - 如何使用reactjs“在警报框中显示表格行值”
- android - 星号红色未在 TextInputEditText 中显示
- rust - 为什么生成在 MPSC 通道上迭代的线程的程序永远不会退出?