在我的应用程序(python,postgres,sqlalchemy)中,我有一个大表tasks
。该应用程序主要使用tasks
中最近的1k行,经常选择和更新行。由于tasks
的大小,这种频繁的操作太慢,所以我决定将此表拆分为两个tasks
tasks_all
,其中表tasks
从tasks_all
继承(postgresql功能)。
因此,应用程序可以非常快速地使用小表,当它对旧数据执行某些操作时,它可以与大表一起使用,包括来自self和来自其后续行的所有行。
以下是我的表的简化类:
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查询,或者可能有更好的解决方案将行从一个表移动到另一个表?
答案 0 :(得分:1)
我发现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")
我知道这个问题是在几年前提出的,但我希望它仍然可以对某人有所帮助。