繁体   English   中英

PostgreSQL 表继承和使用 SQLAlchemy 移动行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM