def record_ticket(self, record, data, hash, app_id):
        # Can use the session instead engine.connection and transaction
        s = self.session
        try:
            q = self.tickets.select(self.tickets.c.record_hash == hash)
            row = s.execute(q).fetchone()
            if row is None:
                row = s.execute(self.tickets.insert().values(
                    record_hash=hash,
                    level=record.level,
                    channel=record.channel or u(''),
                    location=u('%s:%d') % (record.filename, record.lineno),
                    module=record.module or u('<unknown>'),
                    occurrence_count=0,
                    solved=False,
                    app_id=app_id
                ))
                ticket_id = row.inserted_primary_key[0]
            else:
                ticket_id = row['ticket_id']
            s.execute(self.occurrences.insert()
                      .values(ticket_id=ticket_id,
                              time=record.time,
                              app_id=app_id,
                              data=json.dumps(data)))
            s.execute(
                self.tickets.update()
                .where(self.tickets.c.ticket_id == ticket_id)
                .values(occurrence_count=self.tickets.c.occurrence_count + 1,
                        last_occurrence_time=record.time,
                        solved=False))
            s.commit()
        except Exception:
            s.rollback()
            raise
        # Closes the session and removes it from the pool
        s.remove()
Records a log record as ticket.
dataset/ETHPy150Open getlogbook/logbook/logbook/ticketing.py/SQLAlchemyBackend.record_ticket