我有两个相同的表directory = os.path.dirname(os.path.realpath(tkFileDialog.askopenfilename()))
和post
。我有一个查询旧帖子的查询。我想将查询返回的行移到表old_post
中并删除表old_post
中的行。
我可以通过迭代初始查询返回的结果并以这种方式更新我的结果来解决这个问题,但是我担心这是非常低效的,当我有1000多行时会开始引起我的问题。如何有效地将行从一个表“批量移动”到另一个表?
答案 0 :(得分:4)
您可以在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()
答案 1 :(得分:4)
查询旧Posts
。批量插入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
操作的文档和警告。