# Buggy code
def merge_nick_groups(self, first_nick, second_nick):
    """Merges the nick groups for the specified nicks.

    Takes two nicks, which may or may not be registered.  Unregistered
    nicks will be registered. Keys which are set for only one of the given
    nicks will be preserved. Where multiple nicks have values for a given
    key, the value set for the first nick will be used.

    Note that merging of data only applies to the native key-value store.
    If modules define their own tables which rely on the nick table, they
    will need to have their merging done separately."""
    first_id = self.get_nick_id(Identifier(first_nick))
    second_id = self.get_nick_id(Identifier(second_nick))
    self.execute(
        "UPDATE OR IGNORE nick_values SET nick_id = ? WHERE nick_id = ?",
        [first_id, second_id],
    )
    self.execute("DELETE FROM nick_values WHERE nick_id = ?", [second_id])
    self.execute(
        "UPDATE nicknames SET nick_id = ? WHERE nick_id = ?", [first_id, second_id]
    )


# Traceback (OperationalError)
Traceback (most recent call last):
File "/home/TrollOP/willie/willie/bot.py", line 634, in call
exit_code = func(willie, trigger)
File "/home/TrollOP/willie/willie/modules/seen.py", line 50, in note
bot.db.set_nick_value(trigger.nick, 'seen_timestamp', time.time())
File "/home/TrollOP/willie/willie/db.py", line 150, in set_nick_value
nick_id = self.get_nick_id(nick)
File "/home/TrollOP/willie/willie/db.py", line 114, in get_nick_id
[slug]).fetchone()
File "/home/TrollOP/willie/willie/db.py", line 64, in execute
return cur.execute(*args, **kwargs)
OperationalError: database is locked

Traceback (most recent call last):
File "/home/TrollOP/willie/willie/bot.py", line 634, in call
exit_code = func(willie, trigger)
File "/home/TrollOP/willie/willie/modules/weather.py", line 129, in weather
woeid = bot.db.get_nick_value(trigger.nick, 'woeid')
File "/home/TrollOP/willie/willie/db.py", line 161, in get_nick_value
[nick.lower(), key]
File "/home/TrollOP/willie/willie/db.py", line 64, in execute
return cur.execute(*args, **kwargs)
OperationalError: database is locked

Traceback (most recent call last):
File "/home/TrollOP/willie/willie/bot.py", line 634, in call
exit_code = func(willie, trigger)
File "/home/TrollOP/willie/willie/modules/seen.py", line 50, in note
bot.db.set_nick_value(trigger.nick, 'seen_timestamp', time.time())
File "/home/TrollOP/willie/willie/db.py", line 152, in set_nick_value
[nick_id, key, value])
File "/home/TrollOP/willie/willie/db.py", line 64, in execute
return cur.execute(*args, **kwargs)
OperationalError: database is locked

# Fixed code
def merge_nick_groups(self, first_nick, second_nick):
    """Merges the nick groups for the specified nicks.

    Takes two nicks, which may or may not be registered.  Unregistered
    nicks will be registered. Keys which are set for only one of the given
    nicks will be preserved. Where multiple nicks have values for a given
    key, the value set for the first nick will be used.

    Note that merging of data only applies to the native key-value store.
    If modules define their own tables which rely on the nick table, they
    will need to have their merging done separately."""
    first_id = self.get_nick_id(Identifier(first_nick))
    second_id = self.get_nick_id(Identifier(second_nick))
    session = self.ssession()
    try:
        # Get second_id's values
        res = session.query(NickValues).filter(NickValues.nick_id == second_id).all()
        # Update first_id with second_id values if first_id doesn't have that key
        for row in res:
            first_res = (
                session.query(NickValues)
                .filter(NickValues.nick_id == first_id)
                .filter(NickValues.key == row.key)
                .one_or_none()
            )
            if not first_res:
                self.set_nick_value(first_nick, row.key, _deserialize(row.value))
        session.query(NickValues).filter(NickValues.nick_id == second_id).delete()
        session.query(Nicknames).filter(Nicknames.nick_id == second_id).update(
            {"nick_id": first_id}
        )
        session.commit()
    except SQLAlchemyError:
        session.rollback()
        raise
    finally:
        session.close()