Blackbaud CRM中构成记录的ContextRecordID正确格式是什么? (转换数据类型时出错)

问题描述 投票:0回答:1

我正在尝试对Blackbaud CRM进行API调用,以获取包含成分股电子邮件地址的数据列表。我已经将SOAP请求格式化为jinja2模板,并且正在使用python和请求进行调用。这是SOAP请求的规范:

POST /1234ABC_fa123b46-12a4-4119-a334-5678e2e59d29/appfxwebservice.asmx HTTP/1.1
Host: bbisec04pro.blackbaudhosting.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "Blackbaud.AppFx.WebService.API.1/DataListLoad"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <DataListLoadRequest xmlns="Blackbaud.AppFx.WebService.API.1">
      <DataListID>guid</DataListID>
      <DataListName>string</DataListName>
      <ContextRecordID>string</ContextRecordID>
      <Parameters>
        <Values xmlns="bb_appfx_dataforms">
          <fv ID="string">
            <Value />
            <ValueTranslation>string</ValueTranslation>
          </fv>
          <fv ID="string">
            <Value />
            <ValueTranslation>string</ValueTranslation>
          </fv>
        </Values>
      </Parameters>
      <MaxRows>int</MaxRows>
      <MaxTotalRecords>int</MaxTotalRecords>
      <ViewFormID>guid</ViewFormID>
      <RecordIDColumn>string</RecordIDColumn>
      <IncludeMetaData>boolean</IncludeMetaData>
      <SecurityContext>
        <SecurityFeatureID>guid</SecurityFeatureID>
        <SecurityFeatureType>None or Form or DataList or RecordOperation or BusinessProcess or Dashboard or SearchList or SimpleDataList or Task or SmartQuery or AdHocQueryView or BatchType or AddCodeTableEntry or UpdateCodeTableEntry or DeleteCodeTableEntry or Batch or BatchTemplate or Kpi or MergeTask or SmartField or GlobalChange or ReportParameter or SystemPrivilege or ConfigurationData or BatchTemplateCustomize or BatchProcessor or Page or MapEntity or ExportDefinition</SecurityFeatureType>
        <RecordContext>
          <RecordID>string</RecordID>
          <RecordType>string</RecordType>
        </RecordContext>
        <AttributeContext>
          <AttributeCategoryID>string</AttributeCategoryID>
        </AttributeContext>
      </SecurityContext>
      <IgnoreInvalidFilters>boolean</IgnoreInvalidFilters>
      <ResultsAsXml>boolean</ResultsAsXml>
      <UserSettingsPath>string</UserSettingsPath>
      <SortFieldID>string</SortFieldID>
      <SortDirection>Ascending or Descending</SortDirection>
      <StartRowIndex>int</StartRowIndex>
      <RecordToInclude>string</RecordToInclude>
      <RowRangeKeyToRemove>string</RowRangeKeyToRemove>
      <CancelID>string</CancelID>
      <IgnoreExtraFields>boolean</IgnoreExtraFields>
    </DataListLoadRequest>
  </soap:Body>
</soap:Envelope>

这是我的jinja2模板:

{% extends 'client_app.xml' %}
{% block request %}<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <DataListLoadRequest xmlns="Blackbaud.AppFx.WebService.API.1">
      {% block client_app %}{{ super() }}{% endblock %}
      {% if guid %}<DataListID>{{ guid }}</DataListID>{% endif %}
      {% if name %}<DataListName>{{ name }}</DataListName>{% endif %}
      <ContextRecordID>{{ lookup_id }}</ContextRecordID>
      {%  if parameters %}<Parameters>
        <Values xmlns="bb_appfx_dataforms">
          {% for item in parameters %}
          <fv ID="{{ item['id'] }}">
            <Value />
            <ValueTranslation>{{ item['translation'] }}</ValueTranslation>
          </fv>
          {% endfor %}
        </Values>
      </Parameters>{% endif %}
      {% if max_rows %}<MaxRows>{{ max_rows }}</MaxRows>{% endif %}
      {% if max_total %}<MaxTotalRecords>{{ max_total }}</MaxTotalRecords>{% endif %}
      {% if view_id %}<ViewFormID>{{ view_id }}</ViewFormID>{% endif %}
      {% if record_id_col %}<RecordIDColumn>{{ record_id_col }}</RecordIDColumn>{% endif %}
      {% if has_metadata %}<IncludeMetaData>{{ has_metadata }}</IncludeMetaData>{% endif %}
      {% if security_context %}<SecurityContext>
        {% if security_context['guid'] %}<SecurityFeatureID>{{ security_context['guid'] }}</SecurityFeatureID>{% endif %}
        {% if security_context['feature_type'] %}<SecurityFeatureType>{{ security_context['feature_type'] }}</SecurityFeatureType>{% endif %}
        {% if security_context['record'] %}<RecordContext>
          <RecordID>{{ security_context['record']['id'] }}</RecordID>
          <RecordType>{{ security_context['record']['type'] }}</RecordType>
        </RecordContext>{% endif %}
        {% if attribute_context %}<AttributeContext>
          <AttributeCategoryID>{{ attribute_context}}</AttributeCategoryID>
        </AttributeContext>{% endif %}
      </SecurityContext>{% endif %}
      {% if ignore_invalids %}<IgnoreInvalidFilters>{{ ignore_invalids }}</IgnoreInvalidFilters>{% endif %}
      <ResultsAsXml>{{ xml_result }}</ResultsAsXml>
      {% if settings_path %}<UserSettingsPath>{{ settings_path }}</UserSettingsPath>{% endif %}
      {% if sort_id %}<SortFieldID>{{ sort_id }}</SortFieldID>{% endif %}
      {% if sort_direction %}<SortDirection>{{ sort_direction }}</SortDirection>{% endif %}
      {% if start %}<StartRowIndex>{{ start }}</StartRowIndex>{% endif %}
      {% if rec_to_include %}<RecordToInclude>{{ rec_to_include }}</RecordToInclude>{% endif %}
      {% if to_remove %}<RowRangeKeyToRemove>{{ to_remove }}</RowRangeKeyToRemove>{% endif %}
      {% if cancel_id %}<CancelID>{{ cancel_id }}</CancelID>{% endif %}
      {% if ignore_extra %}<IgnoreExtraFields>{{ ignore_extra }}</IgnoreExtraFields>{% endif %}
    </DataListLoadRequest>
  </soap:Body>
</soap:Envelope>
{% endblock %}

这是呈现模板的代码:

def render_data_list(
        guid='',
        name='',
        lookup_id='',
        parameters='',
        max_rows='',
        max_total='',
        view_id='',
        record_id_col='',
        has_metadata='',
        security_context='',
        ignore_invalids='',
        xml_result=0,
        settings_path='',
        sort_id='',
        sort_direction='',
        start='',
        rec_to_include='',
        to_remove='',
        cancel_id='',
        ignore_extra='',
):
    template = env.get_template('data_list_load.xml')
    return template.render(
        guid=guid,
        name=name,
        lookup_id=lookup_id,
        parameters=parameters,
        max_rows=max_rows,
        max_total=max_total,
        view_id=view_id,
        record_id_col=record_id_col,
        has_metadata=has_metadata,
        security_context=security_context,
        ignore_invalids=ignore_invalids,
        xml_result=xml_result,
        settings_path=settings_path,
        sort_id=sort_id,
        sort_direction=sort_direction,
        start=start,
        rec_to_include=rec_to_include,
        to_remove=to_remove,
        cancel_id=cancel_id,
        ignore_extra=ignore_extra,
    )

这里是实际拨打电话的功能:

def get_list(guid='', name='', lookup_id=''):
    endpoint = 'Blackbaud.AppFx.WebService.API.1/DataListLoad'
    header = config.default_head.copy()
    header.update({'SOAPAction': endpoint})
    body = render_data_list(guid=guid, name=name, lookup_id=lookup_id)
    res = config.session.post(
        f'{config.base_url}{config.db_id}{config.api}',
        data=body,
        headers=header,
    )
    print(res.status_code, res.text)

这里是带有参数的实际API调用:

if __name__ == '__main__':
    print(get_list(guid=config.email_list_guid, lookup_id=12345678))

我收到一条错误消息:“无法加载数据列表。将数据类型nvarchar转换为uniqueidentifier时出错。”我尝试将字符串传递给lookup_id,但仍然收到相同的错误。我试图从模板中删除<ContextRecordID>标签,但这些标签似乎是必需的。我正在使用Blackbaud CRM中的组成部分查找ID作为ContextRecordID,因为此数据列表的ContextRecordType是组成部分。我应该使用其他名称作为ContextRecordID还是查找ID的格式不正确?任何帮助,将不胜感激。这是完整的错误响应:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header><ResponseErrorHeader xmlns="Blackbaud.AppFx.WebService.API.1"><Name>DataListLoad</Name><ErrorCode>GeneralError</ErrorCode><ErrorText>Unable to load data list.  Error converting data type nvarchar to uniqueidentifier.</ErrorText><ExceptionDetails>Blackbaud.AppFx.Server.ServiceException: Unable to load data list.  Error converting data type nvarchar to uniqueidentifier. ---&gt; System.Data.SqlClient.SqlException: Error converting data type nvarchar to uniqueidentifier.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean&amp; dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader()
   at System.Data.SqlClient.SqlCommand.InternalEndExecuteReader(IAsyncResult asyncResult, String endMethod)
   at System.Data.SqlClient.SqlCommand.EndExecuteReaderInternal(IAsyncResult asyncResult)
   at System.Data.SqlClient.SqlCommand.EndExecuteReader(IAsyncResult asyncResult)
   at Blackbaud.AppFx.Server.AsyncSupport.CancellableSqlCommandHelper.EndExecuteReader(IAsyncResult asyncResult)
   at Blackbaud.AppFx.Server.DataListLoadProcessor.EndProcessRequest(IAsyncResult asyncResult)
   --- End of inner exception stack trace ---
   at Blackbaud.AppFx.Server.DataListLoadProcessor.EndProcessRequest(IAsyncResult asyncResult)
   at Blackbaud.AppFx.Server.AsyncRequestProcessor`2.EndGetReply(IAsyncResult asyncResult)
   at Blackbaud.AppFx.Server.AppService.EndDispatchRequest(IAsyncResult asyncResult)</ExceptionDetails><RootRequestName>DataListLoadRequest</RootRequestName><RequestProcessorName>Blackbaud.AppFx.Server.DataListLoadProcessor</RequestProcessorName></ResponseErrorHeader></soap:Header><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Server was unable to process request. ---&gt; Unable to load data list.  Error converting data type nvarchar to uniqueidentifier. ---&gt; Error converting data type nvarchar to uniqueidentifier.</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
python-3.x xml soap blackbaud
1个回答
0
投票

查阅ID不是ContextRecordID所期望的。相反,您需要该组成部分的系统记录ID,它是guid。在组成查询的输出中,通常将此值指定为QUERYRECID。 SQL获取所有组成系统记录ID:

select distinct [V_QUERY_CONSTITUENT].[ID]

我将通话更改为:

if __name__ == '__main__':
    print(get_list(guid=config.email_list_guid,
                   system_id='c7bb123f-1f9a-49a4-b2fc-456be05bc334'))

请注意,我将lookup_id的所有实例都更改为system_id

© www.soinside.com 2019 - 2024. All rights reserved.