SQLAlchemy aggiornamento in caso di unica chiave esiste

Ho una classe:

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

Quando l’aggiunta di tag:

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

Voglio aggiornare esistenti tag.

Di corso, ho potuto ho fatto questo:

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

ma, mantenendo tale logica in Tag classe sembra essere più chiara, forse mi tiene fuori il fucile chirurgia.

Come faccio ad arrivarci?
Io sono abbastanza nuovo per Python e SQLAlchemy, quindi, di eventuali ulteriori pensieri sul mio codice sarà apprezzato.

Grazie.

P. S. SQLAlchemy è COSÌ GIGANTESCO e non forniscono un modo semplice per fare INSERT ... ON DUPLICATE KEY UPDATE, eh? WOW!

  • provare sessione.merge(tag) invece di sessione.aggiungere(tag)
  • +100 della S. P.
InformationsquelleAutor Nemoden | 2012-03-28

 

2 Replies
  1. 11

    Dalla versione 1.2 SQLAlchemy sarà di supporto on_duplicate_key_update per MySQL

    C’è anche esempi di come usarlo:

    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)

    Dalla versione 1.1 SQLAlchemy supporto on_conflict_do_update per PostgreSQL

    Esempi:

    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)

Lascia un commento