def get_source(self, source_id=None, source_name=None):
        """Returns a dict with keys ['id', 'name', 'description'] or None if
        no match. The ``id`` field is guaranteed to be an int that
        exists in table source. Requires exactly one of ``source_id``
        or ``source_name``. A new source corresponding to
        ``source_name`` is created if necessary.

        """

        if not (bool(source_id) ^ bool(source_name)):
            raise ValueError('exactly one of source_id or source_name is required')

        if source_id:
            try:
                source_id = int(source_id)
            except (ValueError, TypeError):
                raise ValueError(
                    'source_id must be an int or a string representing one')

            sel = select([self.source], self.source.c.id == source_id).execute()
        else:
            sel = select([self.source], self.source.c.name == source_name).execute()

        result = sel.fetchone()
        if not result:
            raise ValueError(
                'there is no source with id {} or name {}'.format(
                    source_id, source_name))

        return dict(list(zip(list(sel.keys()), result)))
Returns a dict with keys ['id', 'name', 'description'] or None if
        no match. The ``id`` field is guaranteed to be an int that
        exists in table source. Requires exactly one of ``source_id``
        or ``source_name``. A new source corresponding to
        ``source_name`` is created if necessary.