2012-03-28 39 views
12

Tôi đã có một lớp:SQLAlchemy cập nhật nếu khóa duy nhất tồn tại

class Tag(Base, TimestampMixin): 
    """Tags""" 
    __tablename__ = 'tags' 
    __table_args__ = {'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8' } 

    id = Column(Integer(11), autoincrement = True, primary_key = True) 
    tag = Column(String(32), nullable = False, unique = True) 
    cnt = Column(Integer(11), index = True, nullable = False, default = 1) 

    def __init__(self, tag): 
     t = session.query(Tag).filter_by(tag=tag).first() 
     if t: 
      self.cnt = t.cnt+1 
      self.tag = t.tag 
     else: 
      self.tag = tag 

    def __repr__(self): 
     return "<Tag('%s')>" % (self.tag,) 

    def __unicode__(self): 
     return "%s" % (self.tag,) 

Khi thêm tag:

tag = Tag('tag') 
session.add(tag) 
session.commit() 

Tôi muốn nó để cập nhật hiện tag.

Tất nhiên, tôi có thể đã làm điều này:

tag = session.query(Tag).filter_by(tag='tag').first() 
if tag: 
    tag.cnt++ 
else: 
    tag = Tag('tag') 
session.add(tag) 
session.commit() 

nhưng, giữ logic như vậy trong Tag lớp có vẻ là rõ ràng hơn - có thể giữ cho tôi ra khỏi cuộc phẫu thuật shotgun.

Làm cách nào để đến đó? Tôi khá mới với PythonSQLAlchemy, vì vậy mọi ý tưởng bổ sung trên mã của tôi sẽ được đánh giá cao.

Cảm ơn bạn.

P.S. SQLAlchemy là SO GIGANTIC và chúng không cung cấp cách tiện dụng để thực hiện INSERT ... ON DUPLICATE KEY UPDATE, huh? WOW!

+2

thử session.me rge (tag) thay vì session.add (tag) –

Trả lời

6

Từ phiên bản 1.2 SQLAlchemy sẽ hỗ trợ on_duplicate_key_update cho MySQL

Ngoài ra còn có examples về cách sử dụng nó:

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.values.data, 
    status='U' 
) 

conn.execute(on_duplicate_key_stmt) 

Từ phiên bản 1.1 SQLAlchemy hỗ trợ on_conflict_do_update cho PostgreSQL

Examples:

from sqlalchemy.dialects.postgresql import insert 

insert_stmt = insert(my_table).values(
    id='some_existing_id', 
    data='inserted value') 

do_update_stmt = insert_stmt.on_conflict_do_update(
    constraint='pk_my_table', 
    set_=dict(data='updated value') 
) 

conn.execute(do_update_stmt) 
Các vấn đề liên quan