2016-03-25 11 views
4

2つの同一のテーブルpostold_postがあります。古い投稿をチェックするクエリがあります。クエリによって返された行をテーブルold_postに移動し、テーブルpostから行を削除したいと思います。SQLAlchemyを使用して1つのテーブルから別のテーブルに一括移動する

最初のクエリで返された結果を反復処理して結果を更新することでこれを解決できますが、これは非常に非効率で、1,000以上の行があると問題が発生することになります。 1つのテーブルから別のテーブルに効率的に行をバルク移動するにはどうすればよいですか?あなたは、DELETEのためのPostgreSQL

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

CTEのサポートを使用することができます

+0

なぜあなたもそれらを移動しようとしていますか? – davidism

+0

私のアプリケーションの一部の機能です。 – Joshua

+0

なぜ機能ですか?古い投稿を別のテーブルに移動するには、どのような方法がありますか?必要なときに通常のテーブルの古い投稿を照会するだけです。またはビューを作成します。 – davidism

答えて

3

クエリのようになります。SQLAlchemyの1.1では

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() 

生のSQLを実行することができます。大量挿入OldPostsに古いPosts'データが含まれています。古い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インスタンスを受け取り、列のキーと値のうちの辞書を作成します。 insertバルクとdelete操作の使用に関するドキュメントと警告をお読みください。

4

はSQLAlchemyの1.1に追加されます。現在のリリースでは、それが古いPostsため、この

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() 
関連する問題