2012-03-28 14 views
12

existiert Ich habe eine Klasse bekam:SQLAlchemy Update, wenn eindeutige Schlüssel

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

Wenn Tag hinzufügen:

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

ich möchte es tag bestehende zu aktualisieren.

Natürlich könnte ich getan habe dies:

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

aber in Tag Klasse eine solche Logik zu halten scheint klar zu sein - vielleicht hält mich von der Schrotflinte Operation ab.

Wie komme ich dorthin? Ich bin ziemlich neu zu Python und SQLAlchemy, so dass zusätzliche Gedanken zu meinem Code geschätzt werden.

Vielen Dank.

P.S. SQLAlchemy ist SO GIGANTIC und sie bieten keine praktische Möglichkeit zu tun INSERT ... ON DUPLICATE KEY UPDATE, nicht wahr? BEEINDRUCKEND!

+2

try session.me rge (tag) anstelle von session.add (tag) –

Antwort

6

Ab Version 1.2 SQLAlchemy on_duplicate_key_update für MySQL unterstützt

Es gibt auch examples, wie zu verwenden es:

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) 

Ab Version 1.1 SQLAlchemy Unterstützung on_conflict_do_update für 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) 
Verwandte Themen