SQLAlchemy预取列顺序
我的模型比较复杂,我想把现有的存储过程里的逻辑转换成SQLAlchemy(为了便于移植)。
不过,我在处理未提交的数据时遇到了困难。
我有一个 user
表:包含用户ID和名字。我还有一个 status
表:包含状态ID和名字。还有一个 user_statuses
表:包含ID、用户ID、状态ID、开始时间和结束时间。
现在,我需要在一个事务中填充这三个表,要么全部成功,要么全部失败。问题是:
user = User(name = 'Test')
status = Status(name = 'Active')
db.session.add(user)
db.session.add(status)
# Oooopa! This is where it fails
user_session = UserStatuses(user_id=user.id, status_id=status.id, datetime.utcnow(), datetime(9999,01,01,00,00,00))
# both user.id and status.id = None as it's uncommited!
基本上,我需要在不使用显式SQL的情况下访问这些表的顺序。为什么呢?因为要便于移植。目前我使用的是PGSQL,可以这样做:
class User(Base):
....
@staticmethod
def prefetch_id():
db.session.execute("SELECT NEXTVAL('user_id_seq');").scalar()
如果把数据库引擎换成MySQL,哐当一下!应用就坏了。
有没有什么办法可以做到这一点?要考虑到,这可能是一个高交易量的应用,同时会有成千上万的用户在访问。
2 个回答
19
找到了答案——不知道为什么之前没注意到这一点!
Sequence对象还可以像SQL表达式那样独立执行,这样做的效果就是调用它的“下一个值”功能:
seq = Sequence('some_sequence')
nextid = connection.execute(seq)
4
如果你在添加模型对象后,但在提交之前刷新了会话:
db.session.add(user)
db.session.add(status)
db.session.flush()
那么被add()
添加的对象会更新它们的序列列(id
),这样user.id
和status.id
就不会再是None
了。