pandas 如何将从salesforce中提取的表格式化为python?

cld4siwp  于 2023-05-05  发布在  Python
关注(0)|答案(3)|浏览(110)

我能够使用python从salesforce中提取一些字段。
我使用了以下代码块:

!pip install simple_salesforce 

from simple_salesforce import Salesforce
import pandas as pd

sf = Salesforce(
username='', 
password='', 
security_token='')

sf_data = sf.query_all("SELECT Brand_Name__c,Name FROM AuthorisedProduct__c")

sf_df = pd.DataFrame(sf_data)

sf_df.head()

此过程将所有项目放在一个“记录”字段中。
| 记录|总尺寸|
| --------------|--------------|
| OrderedDict([('attributes ',OrderedDict([('type','AuthorisedProduct__c'),('url','/services/data/v42.0/sobjects/AuthorisedProduct__c/a020o0000xC1fmAAC')])),('Brand_Name__c',' ABB'),('Name ','UNO-DM-1.2-TL-PLUS-B')])|一万四千|
| OrderedDict([('attributes ',OrderedDict([('type','AuthorisedProduct__c'),('url','/services/data/v42.0/sobjects/AuthorisedProduct__c/a020o0000xC1fnAAC')])),('Brand_Name__c',' ABB'),('Name ','UNO-DM-1.2-TL-PLUS-SB')])|一万四千|
| OrderedDict([('attributes ',OrderedDict([('type','AuthorisedProduct__c'),('url','/services/data/v42.0/sobjects/AuthorisedProduct__c/a020o0000xC1foAAC')]),('Brand_Name__c',' ABB'),('Name ','UNO-DM-2.0-TL-PLUS-B')])|一万四千|
请注意,记录下有14000个值。我希望在一个简单的 Dataframe 中只有两个字段。具有“Brand_Name__c”和“Name”字段的表。
| 品牌名称__C|姓名|
| --------------|--------------|
| ABB| UNO-DM-2.0-TL-PLUS-B |
| ABB| UNO-DM-1.2-TL-PLUS-SB |
我们将得到一个14000乘2的矩阵。
请告知如何实现这一目标?
那么,如何逆转这一过程呢?
非常感谢大家。

vtwuwzda

vtwuwzda1#

您必须了解Salesforce发送的JSON响应的实际形状,其中包括一个顶级"records"键,所有数据都包含在该键下。此外,除了您实际请求的字段的数据之外,每个记录条目还包含一个"attributes"键。您无法更改JSON响应的形状。
simple_salesforce documentation中提供了一个示例,展示了如何为Pandas消化此API响应:
从SFDC API查询(例如query、query_all)生成Pandas数据框架

import pandas as pd

sf.query("SELECT Id, Email FROM Contact")

df = pd.DataFrame(data['records']).drop(['attributes'],axis=1)
wh6knrhe

wh6knrhe2#

您可以在records列中解包OrderedDict对象:

from collections import OrderedDict
import pandas as pd

df = pd.DataFrame({
    'records':[
        OrderedDict([('attributes', OrderedDict([('type', 'AuthorisedProduct__c'), ('url', '/services/data/v42.0/sobjects/AuthorisedProduct__c/a020o00000xC1fmAAC')])), ('Brand_Name__c', 'ABB'), ('Name', 'UNO-DM-1.2-TL-PLUS-B')]),
        OrderedDict([('attributes', OrderedDict([('type', 'AuthorisedProduct__c'), ('url', '/services/data/v42.0/sobjects/AuthorisedProduct__c/a020o00000xC1fnAAC')])), ('Brand_Name__c', 'ABB'), ('Name', 'UNO-DM-1.2-TL-PLUS-SB')]),
        OrderedDict([('attributes', OrderedDict([('type', 'AuthorisedProduct__c'), ('url', '/services/data/v42.0/sobjects/AuthorisedProduct__c/a020o00000xC1foAAC')])), ('Brand_Name__c', 'ABB'), ('Name', 'UNO-DM-2.0-TL-PLUS-B')])
    ],
    'total size': [14000]*3
})

df['Brand_Name__c'] = df['records'].apply(lambda x: x['Brand_Name__c'])
df['Name'] = df['records'].apply(lambda x: x['Name'])

结果:

>>> df
                                             records  total size Brand_Name__c                   Name
0  {'attributes': {'type': 'AuthorisedProduct__c'...       14000           ABB   UNO-DM-1.2-TL-PLUS-B
1  {'attributes': {'type': 'AuthorisedProduct__c'...       14000           ABB  UNO-DM-1.2-TL-PLUS-SB
2  {'attributes': {'type': 'AuthorisedProduct__c'...       14000           ABB   UNO-DM-2.0-TL-PLUS-B
8ljdwjyq

8ljdwjyq3#

对于任何人仍然感兴趣的这个主题,我做了一个包来解决这个一劳永逸。它可以递归地取消嵌套,这样你就可以进行多级关系查询(而不仅仅是两级),并得到一个普通的 Dataframe 作为输出。
pip install simpler-sf

import simpler_sf
simpler_sf.simple_salesforce()
import simple_salesforce

sf = simple_salesforce.Salesforce(...)

query = 'SELECT Contact.Id, Account.Name, Campaign FROM CampaignMember'

df = sf.smart_query(query)
print(df)

输出:

Contact.FirstName   Account.Name           Campaign
0   Emily                     Amazon   CampaignA_2023Q2
1   Jasmine                   Amazon   CampaignA_2023Q2
2   Míng                   Microsoft   CampaignB_2022Q4

这是github repo的链接

相关问题