2016-03-25 18 views
4

ile bir tablodan diğerine satırları toplu taşıma post ve old_post iki aynı tablo var. Eski gönderileri kontrol eden bir sorgum var. Sorgu tarafından döndürülen satırları old_post tablosuna taşımak ve satırları tablo post'dan silmek istiyorum.SQLAlchemy

Bunu, ilk sorgu tarafından döndürülen sonuçları yineleyerek ve sonuçlarımı bu şekilde güncelleştirerek çözebilirim, ancak endişeleniyorum, bu çok verimsiz ve 1000+ satır olduğunda sorunlara neden olmaya başlayacağım. Satırları bir tablodan diğerine nasıl verimli bir şekilde "toplu taşıyabilirim?"

+0

Neden onları taşımaya çalışıyorsunuz? – davidism

+0

Uygulamamın bir kısmı için bir özellik. – Joshua

+0

Neden bu bir özellik? Eski mesajları farklı bir masaya taşımak için ne gibi bir kullanım var? İhtiyacınız olduğunda normal tablodaki eski gönderileri sorgulamanız yeterlidir. Veya bir görünüm oluşturun. – davidism

cevap

3

Query gibi görünecektir sqlalchemy 1.1 yılında ham 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() 

yürütebilirsiniz. Eski Posts' verileriyle toplu olarak OldPosts ekleyin. Eski Posts'u toplu olarak silin.

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 fonksiyon Post örneğini alır ve sütun anahtar ve değerlerin dışında bir sözlük oluşturur. Toplu olarak insert ve delete işlemlerini kullanma hakkında dokümanlar ve uyarılar okuyun.

4

Sen SİL için

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

CTE destek sqlalchemy 1.1 eklenecektir PostgreSQL içinde Common Table Expressions kullanabilirsiniz. Geçerli sürümde bunu eski Posts için bu

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