【问题标题】:Bulk move rows from one table to another with SQLAlchemy使用 SQLAlchemy 将行从一个表批量移动到另一个表
【发布时间】:2016-07-13 11:45:06
【问题描述】:

我有两个相同的表postold_post。我有一个检查旧帖子的查询。我想将查询返回的行移到表old_post 中,并从表post 中删除行。

我可以通过迭代初始查询返回的结果并以这种方式更新我的结果来解决这个问题,但是我担心这非常低效并且当我有 1,000 多行时会开始给我带来问题。如何有效地将行从一个表“批量移动”到另一个表?

【问题讨论】:

    标签: python postgresql flask sqlalchemy


    【解决方案1】:

    您可以在 PostgreSQL 中使用Common Table Expressions

    WITH moved_posts AS (
        DELETE FROM post
        WHERE expiry > time_stamp
        RETURNING *
    )
    INSERT INTO old_post
    SELECT * from moved_posts
    

    SQLAlchemy 1.1 中将添加对 DELETE 的 CTE 支持。在当前版本中,您可以执行原始 SQL

    from sqlalchemy import text
    
    sql = text('''
    WITH moved_posts AS (
        DELETE FROM post
        WHERE expiry > ?
        RETURNING *
    )
    INSERT INTO old_post
    SELECT * from moved_posts
    ''')
    db.session.execute(sql, [time_stamp])
    db.session.commit()
    

    在 SQLAlchemy 1.1 中它看起来像这样

    posts = Post.__table__
    old_posts = OldPost.__table__
    moved_posts = (
        posts.delete()
        .where(posts.c.expiry > ts)
        .returning(*(posts.c._all_columns))
        .cte('moved_posts'))
    insert = (
        old_posts.insert()
        .from_select(
            [c.name for c in moved_posts.columns],
            moved_posts.select()
        ))
    db.session.execute(insert)
    db.session.commit()
    

    【讨论】:

      【解决方案2】:

      查询旧的Posts。使用旧的 Posts' 数据批量插入 OldPosts。批量删除旧的Posts

      keys = db.inspect(Post).columns.keys()
      get_columns = lambda post: {key: getattr(post, key) for key in keys}
      
      posts = Post.query.filter(Post.expiry > ts)
      db.session.bulk_insert_mappings(OldPost, (get_columns(post) for post in posts))
      posts.delete()
      db.session.commit()
      

      get_columns 函数采用Post 实例并根据列键和值创建字典。阅读有关使用批量 insertdelete 操作的文档和警告。

      【讨论】:

        猜你喜欢
        • 2012-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-18
        • 2016-03-22
        • 1970-01-01
        • 2015-04-15
        • 2013-06-03
        相关资源
        最近更新 更多