sqlalchemy 实现 mysql INSERT INTO...ON DUPLICATE KEY UPDATE语法
1. 前言
myql的INSERT INTO...ON DUPLICATE KEY UPDATE语句,简单点来说,就是如果记录不存在,则插入,如果记录存在,则更新。
那怎么判断记录存在否?—— 主键、唯一键。
那不是可以使用replace语句吗?—— 原理上可以,但是sqlalchemy orm中的的实现,是使用merge语法,这个语法有一个限制,就是判断是否已经存在记录的时候,只检查主键,不检查唯一键。
因此使用sqlalchemy中对INSERT INTO...ON DUPLICATE KEY UPDATE的实现。
2. 实现
官网给的例子[1]:
from sqlalchemy.dialects.mysql import insert insert_stmt = insert(my_table).values( id='some_existing_id', data='inserted value') on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update( data=insert_stmt.inserted.data, status='U' ) print(on_duplicate_key_stmt) conn.execute(on_duplicate_key_stmt)
是不是很迷,整体来说sqlalchemy给的文档都比较迷,解释一下:
- insert(my_table):table表示你orm中定义的关于表的model类,譬如你有个test的表,里面只有四个字段,id,a,b,c,你orm中定义的model类如下:
1 from sqlalchemy.ext.declarative import declarative_base 2 Base = declarative_base() 3 4 class Test(Base): 5 __tablename__ = "test" 6 id = Column(Integer, primary_key=True, index=True) 7 a = Column(Integer) 8 b = Column(String(36)) 9 c = Column(String(50)) 10 11 __table_args__ = ( 12 UniqueConstraint("b", "c", name='uni_bc'), 13 )
可以看到,主键为id,另外b_c构成一个联合唯一键。
- insert(my_table).values:后面的参数表示插入的数据(key value),如
insert_stmt = insert(Test).values( a=1, b='newb', c='newc')
- insert_stmt.on_duplicate_key_update表示如果记录存在,需要更新那些字段,键值对的规则如上:
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update( c='newerc')
- conn.execute(on_duplicate_key_stmt):conn为你的db 连接会话。
当然,大部分时候,你不想手动指定每个字段,而是将所有需要插入的字段都放在dict中,如果不存在则插入,存在则更新,则直接使用Python的解包语法糖即可:
new_record = { a = 1, b = 'newb', c = 'newc' } insert_stmt = insert(Test).values(**new_record) on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(**new_record) conn.execute(on_duplicate_key_stmt)
基本就是实现replace into的效果了,如果有其他方法的朋友请不吝留言。
3. 参考
[1] INSERT…ON DUPLICATE KEY UPDATE (Upsert)
(完)
本文版权归作者(https://www.cnblogs.com/harrymore/)和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,如有问题, 可邮件(harrymore@126.com)咨询.