def getFieldData(opsimDb, sqlconstraint):
    """
    Find the fields (ra/dec/fieldID) relevant for a given sql constraint.
    If the opsimDb contains a Fields table, it uses
    :meth:`rubin_sim.maf.OpsimDatabase.fetchFieldsFromFieldTable()`
    to get the fields. If the opsimDb contains only a Summary, it uses
    :meth:`rubin_sim.maf.OpsimDatabase.fetchFieldsFromSummaryTable()`.

    Parameters
    ----------
    opsimDb : `rubin_sim.maf.db.OpsimDatabase`
        An opsim database to use to query for field information.
    sqlconstraint : `str`
        A SQL constraint to apply to the query (i.e. find all fields for DD proposal)

    Returns
    -------
    numpy.ndarray
        A numpy structured array containing the field information.  This data will ALWAYS be in radians.
    """
    # Get all fields used for all proposals.
    if 'proposalId' not in sqlconstraint:
        propids, propTags = opsimDb.fetchPropInfo()
        propids = list(propids.keys())
    else:
        # Parse the propID out of the sqlconstraint.
        # example: sqlconstraint: filter = r and (propid = 219 or propid = 155) and propid!= 90
        sqlconstraint = sqlconstraint.replace('=', ' = ').replace('(', '').replace(')', '')
        sqlconstraint = sqlconstraint.replace("'", '').replace('"', '')
        # Allow for choosing all but a particular proposal.
        sqlconstraint = sqlconstraint.replace('! =', ' !=')
        sqlconstraint = sqlconstraint.replace('  ', ' ')
        sqllist = sqlconstraint.split(' ')
        propids = []
        nonpropids = []
        i = 0
        while i < len(sqllist):
            if sqllist[i].lower() == 'proposalid':
                i += 1
                if sqllist[i] == "=":
                    i += 1
                    propids.append(int(sqllist[i]))
                elif sqllist[i] == '!=':
                    i += 1
                    nonpropids.append(int(sqllist[i]))
            i += 1
        if len(propids) == 0:
            propids, propTags = opsimDb.fetchPropInfo()
            propids = list(propids.keys())
        if len(nonpropids) > 0:
            for nonpropid in nonpropids:
                if nonpropid in propids:
                    propids.remove(nonpropid)
    # And query the field Table.
    if 'Field' in opsimDb.tables:
        # The field table is always in degrees.
        fieldData = opsimDb.fetchFieldsFromFieldTable(propids, degreesToRadians=True)
    # Or give up and query the summary table.
    else:
        fieldData = opsimDb.fetchFieldsFromSummaryTable(sqlconstraint)
    return fieldData