[英]PostgreSQL table inheritance and moving rows with SQLAlchemy
在我的应用程序(python、postgres、sqlalchemy)中,我有一个大表tasks
。 该应用程序主要处理tasks
最近的 1k 行,经常选择和更新行。 由于tasks
大小,这种频繁的操作太慢了,所以我决定将此表拆分为两个tasks
tasks_all
,其中表tasks
继承自tasks_all
(postgresql 功能)。
因此,该应用程序可以非常快速地处理小表,并且当它对旧数据执行某些操作时,它可以处理大表,其中包括来自自身及其后继者的所有行。
这是我的表的简化类:
class TaskBase:
def __init__(self, id, parent_id, data):
self.id = id
self.parent_id = parent_id
self.data = data
def __repr__(self):
return '<Task: {} {}>'.format(self.id, self.data)
class Task(TaskBase, Base):
__tablename__ = 'tasks'
id = Column(INT, primary_key=True)
parent_id = Column(INT, ForeignKey('tasks.id'))
data = Column(TEXT)
children = relationship("Task", backref=backref('parent', remote_side=[id]))
class TaskAll(TaskBase, Base):
__tablename__ = 'tasks_all'
id = Column(INT, primary_key=True)
parent_id = Column(INT, ForeignKey('tasks_all.id'))
data = Column(TEXT)
children = relationship("TaskAll", backref=backref('parent', remote_side=[id]))
为了保持tasks
表很小,我需要不时地将行从tasks
移动到tasks_all
。 有时我需要将它们移回去。 以下代码是我尝试实现移动的方式。
def move_group(ids):
query = session.query(TaskAll).filter(TaskAll.id in ids)
db_session.s.execute(insert(Task).from_select((
TaskAll.id,
TaskAll.parent_id,
TaskAll.data,
), query))
print("insert from select is successful")
query.delete()
print("delete is successful")
但是,这并不工作,因为如表tasks_all
是家长tasks
,删除tasks_all
也删除tasks
。 结果 SQL 查询是:
DELETE FROM tasks_all WHERE tasks_all.id IN (...);
但是要执行我需要的操作,查询应该是
DELETE FROM ONLY tasks_all WHERE tasks_all.id IN (...);
据我所知,SQLAlchemy 对ONLY
一无所知。 我是否必须使用 sqla 跳过 ORM 部分的原始 SQL 查询,或者可能有更好的解决方案将行从一个表移动到另一个表?
我发现 SQLAlchemy 有一个提示机制,可以帮助在继承的表中执行操作。
def move_group(ids):
query = session.query(TaskAll).filter(TaskAll.id in ids)
db_session.s.execute(insert(Task).from_select((
TaskAll.id,
TaskAll.parent_id,
TaskAll.data,
), query))
print("insert from select is successful")
query.delete().with_hint('ONLY', dialect_name='postgresql')
print("delete is successful")
我知道这个问题是几年前提出的,但我希望它仍然可以帮助某人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.