sp_api_client.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. import clickhouse_connect
  2. import time
  3. import warnings
  4. warnings.filterwarnings('ignore')
  5. import numpy as np
  6. from pymysql import Timestamp
  7. from sp_api.util import throttle_retry, load_all_pages
  8. from sp_api.api import Orders,ListingsItems,Inventories,Reports
  9. from sp_api.base import Marketplaces,ReportType,ProcessingStatus
  10. import pandas as pd
  11. import gzip
  12. from io import BytesIO,StringIO
  13. from datetime import datetime, timedelta,timezone
  14. import pytz
  15. import time
  16. from sync_amz_data.public.amz_ad_client import shop_infos
  17. from dateutil.parser import parse
  18. import pymysql
  19. class SpApiRequest:
  20. def __init__(self, credentials,marketplace):
  21. self.credentials = credentials
  22. self.marketplace = marketplace
  23. # self.shopInfo = shop_infos('3006125408623189')
  24. # self.timezone = self.shopInfo['time_zone']
  25. # self.profileid = '3006125408623189'
  26. @classmethod
  27. def mysql_connect_auth(cls):
  28. conn = pymysql.connect(user="admin",
  29. password="NSYbBSPbkGQUbOSNOeyy",
  30. host="retail-data.cnrgrbcygoap.us-east-1.rds.amazonaws.com",
  31. database="ansjer_dvadmin",
  32. port=3306)
  33. return conn
  34. def mysql_connect(self):
  35. conn = pymysql.connect(user="huangyifan",
  36. password="123456",
  37. host="192.168.1.18",
  38. database="amz_sp_api",
  39. port=3306)
  40. return conn
  41. def create_report(self,**kwargs):
  42. reportType = kwargs['reportType']
  43. reportOptions =kwargs.get("reportOptions")
  44. dataStartTime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") if kwargs.get("dataStartTime") is None else kwargs.get("dataStartTime")+"T00:00:00"
  45. dataEndTime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") if kwargs.get("dataEndTime") is None else kwargs.get("dataEndTime")+"T23:59:59"
  46. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  47. rel = report.create_report(
  48. reportType=reportType,marketplaceIds=[kwargs['marketpalceids'] if kwargs.get('marketpalceids') is not None else self.marketplace.marketplace_id],
  49. reportOptions=reportOptions,dataStartTime=dataStartTime,dataEndTime=dataEndTime
  50. )
  51. reportId = rel.payload.get("reportId")
  52. # print(reportId)
  53. return reportId
  54. def decompression(self,reportId):
  55. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  56. while True:
  57. reportId_info = report.get_report(reportId=reportId)
  58. # print(reportId_info.payload)
  59. print("please wait...")
  60. if reportId_info.payload.get("processingStatus")==ProcessingStatus.DONE:
  61. reportDocumentId = reportId_info.payload.get("reportDocumentId")
  62. rp_table = report.get_report_document(reportDocumentId=reportDocumentId,download=False)
  63. print(rp_table)
  64. if rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:#
  65. df = pd.read_table(filepath_or_buffer=rp_table.payload['url'],compression={"method":'gzip'},encoding='iso-8859-1')
  66. return df
  67. elif rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  68. df = pd.read_table(filepath_or_buffer=rp_table.payload['url'], compression={"method": 'gzip'},
  69. encoding='Shift-JIS')
  70. # df.columns =
  71. return df
  72. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:
  73. df = pd.read_table(rp_table.payload.get("url"),encoding='iso-8859-1')
  74. return df
  75. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  76. df = pd.read_table(rp_table.payload.get("url"),encoding='Shift-JIS')
  77. return df
  78. elif reportId_info.payload.get("processingStatus") in [ProcessingStatus.CANCELLED,ProcessingStatus.FATAL]:
  79. print("取消或失败")
  80. break
  81. time.sleep(15)
  82. print("please wait...")
  83. def data_deal(self,decom_df,seller_id):
  84. decom_df['mainImageUrl'] = decom_df['seller-sku'].map(lambda x: self.get_mainImage_url(x))
  85. url_columns = [i for i in decom_df.columns if "url" in i.lower()]
  86. if len(url_columns) > 0:
  87. decom_df[url_columns] = decom_df[url_columns].astype("string")
  88. asin_columns = [i for i in decom_df.columns if 'asin' in i.lower()]
  89. if len(asin_columns) > 0:
  90. decom_df[asin_columns] = decom_df[asin_columns].astype("string")
  91. if 'pending-quantity' in decom_df.columns:
  92. decom_df['pending-quantity'] = decom_df['pending-quantity'].map(
  93. lambda x: 0 if pd.isna(x) or np.isinf(x) else x).astype("int32")
  94. deletecolumns = [i for i in decom_df.columns if 'zshop' in i.lower()]
  95. decom_df.drop(columns=deletecolumns, inplace=True)
  96. if 'quantity' in decom_df.columns:
  97. decom_df['quantity'] = decom_df['quantity'].map(lambda x: 0 if pd.isna(x) or np.isinf(x) else x).astype(
  98. "int32")
  99. decom_df['opendate_date'] = decom_df['open-date'].map(lambda x: self.datetime_deal(x))
  100. if 'add-delete' in decom_df.columns:
  101. decom_df['add-delete'] = decom_df['add-delete'].astype('string', errors='ignore')
  102. if 'will-ship-internationally' in decom_df.columns:
  103. decom_df['will-ship-internationally'] = decom_df['will-ship-internationally'].astype('string',errors='ignore')
  104. if 'expedited-shipping' in decom_df.columns:
  105. decom_df['expedited-shipping'] = decom_df['expedited-shipping'].astype('string',errors='ignore')
  106. decom_df['updateTime'] = datetime.now()
  107. decom_df['timezone'] = "UTC"
  108. decom_df['seller_id'] = seller_id
  109. #
  110. decom_df['item-description'] = decom_df['item-description'].str.slice(0,500)
  111. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].fillna(0.0)
  112. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].fillna(0)
  113. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].astype(
  114. 'string')
  115. decom_df.fillna('', inplace=True)
  116. # print(decom_df.info())
  117. return decom_df
  118. def GET_MERCHANT_LISTINGS_ALL_DATA(self,limit=None):
  119. start = time.time()
  120. para = {"reportType":ReportType.GET_MERCHANT_LISTINGS_ALL_DATA}
  121. reportid = self.create_report(**para)
  122. decom_df = self.decompression(reportid)
  123. print("连接数据库")
  124. conn = self.mysql_connect()
  125. print("连接成功")
  126. cursor = conn.cursor()
  127. timezone = "UTC" #pytz.timezone(self.timezone)
  128. bondary_date = (datetime.now()).strftime("%Y-%m-%d") #+ timedelta(days=-28)
  129. cursor.execute(f"""select * from amz_sp_api.productInfo where (mainImageUrl is not null and mainImageUrl not in ('', ' ')) and
  130. (`seller-sku` not in ('',' ') and `seller-sku` is not null) and
  131. `updateTime`>='{bondary_date}'""") #`seller-sku`,`updateTime`,`mainImageUrl`
  132. col = [i[0] for i in cursor.description]
  133. query_rel = cursor.fetchall()
  134. if len(query_rel)!=0:
  135. print(query_rel[0])
  136. df = pd.DataFrame(query_rel,columns=col)
  137. listingid = df['listing-id'].to_numpy().tolist()
  138. decom_df = decom_df.query("`listing-id` not in @listingid")
  139. print("数据条数: ",len(decom_df))
  140. # print(f"delete * from amz_sp_api.productInfo where `listing-id` not in {tuple(listingid)}")
  141. # conn.commit()
  142. if len(decom_df)==0:
  143. return "Done"
  144. if limit != None:
  145. decom_df = decom_df.iloc[:limit,:]
  146. print("getting mainImageInfo...")
  147. rowcount = 0
  148. while rowcount < len(decom_df):
  149. df_insert = decom_df.copy()
  150. df_insert = df_insert.iloc[rowcount:rowcount + 200, :]
  151. df_insert = self.data_deal(df_insert)
  152. list_df = df_insert.to_numpy().tolist()
  153. # print(list(conn.query("select * from amz_sp_api.orderReport")))
  154. sql = f"""
  155. insert into amz_sp_api.productInfo
  156. values (%s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s,%s)
  157. """ #ok
  158. # print(sql)
  159. conn = self.mysql_connect()
  160. cursor = conn.cursor()
  161. try:
  162. conn.begin()
  163. cursor.executemany(sql, list_df)
  164. conn.commit()
  165. print("插入中...")
  166. insert_listingid = df_insert['listing-id'].to_numpy().tolist()
  167. cursor.execute(f"delete from amz_sp_api.productInfo where `listing-id` not in {tuple(insert_listingid)} and `updateTime`<'{bondary_date}'")
  168. conn.commit()
  169. rowcount += 200
  170. except Exception as e:
  171. conn.rollback()
  172. print(e)
  173. try:
  174. conn = self.mysql_connect()
  175. cursor = conn.cursor()
  176. conn.begin()
  177. cursor.executemany(sql, list_df)
  178. conn.commit()
  179. insert_listingid = df_insert['listing-id'].to_numpy().tolist()
  180. cursor.execute(f"delete from amz_sp_api.productInfo where `listing-id` not in {tuple(insert_listingid)} and `updateTime`<'{bondary_date}'")
  181. conn.commit()
  182. except Exception as e:
  183. conn.rollback()
  184. print(e)
  185. break
  186. # break
  187. conn.close()
  188. print("全部完成")
  189. end =time.time()
  190. print("duration:",end-start)
  191. return decom_df
  192. def get_mainImage_url(self, sku):
  193. listingClient = ListingsItems(credentials=self.credentials, marketplace=self.marketplace)
  194. try:
  195. r1 = listingClient.get_listings_item(sellerId=self.shopInfo['advertiser_id'], sku=sku)
  196. img = r1.payload.get("summaries")[0].get("mainImage")
  197. img_url = None if img is None else img.get("link")
  198. except Exception as e:
  199. print("获取图片url过程错误重试, 错误message: ",e)
  200. time.sleep(3)
  201. r1 = listingClient.get_listings_item(sellerId=self.shopInfo['advertiser_id'], sku=sku)
  202. img = r1.payload.get("summaries")[0].get("mainImage")
  203. img_url = None if img is None else img.get("link")
  204. return img_url
  205. def datetime_deal(self,timestring):
  206. timezone_ = {"AEST":"Australia/Sydney",
  207. "AEDT":"Australia/Sydney",
  208. "PST":"America/Los_Angeles",
  209. "PDT":"America/Los_Angeles",
  210. "CST":"America/Chicago",
  211. "CDT":"America/Chicago",
  212. "MET":"MET",
  213. "MEST":"MET",
  214. "BST":"Europe/London",
  215. "GMT":"GMT",
  216. "CET":"CET",
  217. "CEST":"CET",
  218. "JST":"Asia/Tokyo",
  219. "BRT":"America/Sao_Paulo"}
  220. date_list = str.split(timestring,sep = ' ')
  221. if len(date_list)<3:
  222. try:
  223. return datetime.strptime(date_list[0],"%Y-%m-%d")
  224. except:
  225. try:
  226. return datetime.strptime(date_list[0], "%Y/%m/%d")
  227. except:
  228. try:
  229. return datetime.strptime(date_list[0], "%d/%m/%Y")
  230. except Exception as e:
  231. print(e)
  232. return datetime(1999, 12, 31, 0, 0, 0)
  233. try:
  234. time_date = datetime.strptime(date_list[0]+date_list[1],"%Y-%m-%d%H:%M:%S")
  235. timezone = pytz.timezone(timezone_[date_list[2]])
  236. time_ = timezone.localize(time_date)
  237. return time_.astimezone(pytz.UTC)
  238. except:
  239. try:
  240. time_date = datetime.strptime(date_list[0] + date_list[1], "%d/%m/%Y%H:%M:%S")
  241. timezone = pytz.timezone(timezone_[date_list[2]])
  242. time_ = timezone.localize(time_date)
  243. return time_.astimezone(pytz.UTC)
  244. except :
  245. try:
  246. time_date = datetime.strptime(date_list[0] + date_list[1], "%Y/%m/%d%H:%M:%S")
  247. timezone = pytz.timezone(timezone_[date_list[2]])
  248. time_ = timezone.localize(time_date)
  249. return time_.astimezone(pytz.UTC)
  250. except Exception as e1:
  251. print(e1)
  252. return datetime(1999,12,31,0,0,0)
  253. def update_data(self,df,seller_id,country_code,conn):
  254. cursor = conn.cursor()
  255. columns = ['listing-id','seller_id',
  256. 'asin1','seller-sku','country_code',
  257. 'marketplace_id','quantity','fulfillment_channel',
  258. 'price','opendate','status','update_datetime','product-id','product-id-type'
  259. ]
  260. df_data = pd.DataFrame(columns=columns)
  261. delete_list = []
  262. try:
  263. cursor.execute(f"""select * from
  264. ansjer_dvadmin.seller_listings where seller_id='{seller_id}' and country_code='{country_code}'""")
  265. col = [i[0] for i in cursor.description]
  266. query_rel = cursor.fetchall()
  267. df_rel = pd.DataFrame(query_rel, columns=col)
  268. df_rel['quantity'] = df_rel['quantity'].fillna(0).astype('int64')
  269. df_rel['price'] = df_rel['price'].fillna(0.0).astype('float64')
  270. df_rel['product_id_type'] = df_rel['product_id_type'].astype('int64')
  271. df['update_datetime'] =df['update_datetime'].astype('datetime64[ns]')
  272. df['quantity'] = df['quantity'].fillna(0).astype('int64')
  273. df['price']= df['price'].fillna(0.0).astype('float64')
  274. # print(df_rel.dtypes)
  275. # print(df[columns].dtypes)
  276. row = 0
  277. while row < len(df):
  278. temp_df = df.iloc[row, :]
  279. listing_id = temp_df['listing-id']
  280. asin = temp_df['asin1']
  281. sku = temp_df['seller-sku']
  282. quantity = temp_df['quantity']
  283. fulfillment_channel = temp_df['fulfillment_channel']
  284. price = temp_df['price']
  285. product_id = temp_df['product-id']
  286. temp = df_rel.query("""listing_id==@listing_id and asin==@asin and sku==@sku and quantity==@quantity and fulfillment_channel==@fulfillment_channel and price==@price and product_id==@product_id and country_code==@country_code and seller_id==@seller_id""")
  287. print("需要关注数据(是否异常):",len(temp),temp.to_numpy().tolist()) if len(temp)>1 else 1
  288. # print(len(temp))
  289. if len(temp)==0:
  290. df_data = df_data.append(temp_df,ignore_index=True)
  291. delete_list.append((seller_id,country_code,sku,listing_id,product_id))
  292. row += 1
  293. print("判断不同数据条数",len(delete_list))
  294. print("预计更新数据条数",len(df_data))
  295. try:
  296. # print(tuple(delete_list))
  297. if len(delete_list)>0:
  298. query = f"""delete from ansjer_dvadmin.seller_listings
  299. where (seller_id,country_code,sku,listing_id,product_id) in %s""" #where (seller_id,country_code) in %s"""
  300. cursor.execute(query,(delete_list,))
  301. conn.commit()
  302. print(delete_list)
  303. print("进行中...")
  304. except Exception as e:
  305. print(e)
  306. conn.rollback()
  307. return df_data
  308. except Exception as e:
  309. print("错误:", e)
  310. return df
  311. def GET_FLAT_FILE_OPEN_LISTINGS_DATA(self,conn=None,seller_id=None):
  312. para = {"reportType": ReportType.GET_MERCHANT_LISTINGS_ALL_DATA}
  313. reportid = self.create_report(**para)
  314. df = self.decompression(reportid)
  315. if len(df)>0:
  316. if self.marketplace.marketplace_id =='A1VC38T7YXB528':
  317. df.columns = ['item-name','listing-id','seller-sku','price','quantity','open-date','product-id-type','item-description',
  318. 'item-condition','overseas shipping','fast shipping','asin1','stock_number','fulfillment-channel','merchant-shipping-group','status']
  319. df['seller_id'] = seller_id
  320. df['marketplace_id'] = self.marketplace.marketplace_id
  321. df['country_code'] = str(self.marketplace)[-2:]
  322. if 'fulfilment-channel' in df.columns:
  323. print("changed fulfilment-channel:")
  324. print(seller_id,self.marketplace)
  325. df['fulfillment-channel'] = df['fulfilment-channel'].copy()
  326. df['fulfillment_channel'] = df['fulfillment-channel'].map(lambda x:"FBA" if not pd.isna(x) and len(x)>0 and str(x)[1:4] in "AMAZON" else x)
  327. df['fulfillment_channel'] = df['fulfillment_channel'].map(lambda x: "FBM" if not pd.isna(x) and len(x)>0 and str(x)[1:4] in "DEFAULT" else x)
  328. if 'asin1' not in df.columns:
  329. df['asin1'] = ''
  330. if 'product-id' not in df.columns:
  331. df['product-id'] = ''
  332. # 空值处理
  333. df['quantity'] = df['quantity'].fillna(0).astype('int64',errors='ignore')
  334. df[['listing-id','seller_id','asin1','seller-sku','country_code','marketplace_id','fulfillment_channel','status','product-id']] = df[['listing-id','seller_id','asin1','seller-sku','country_code','marketplace_id','fulfillment_channel','status','product-id']].fillna('').astype('string',errors='ignore')
  335. df['price'] = df['price'].fillna(0.0).astype('float64',errors='ignore')
  336. df.fillna('',inplace=True)
  337. # 时间处理
  338. df['opendate'] = df['open-date'].map(lambda x: self.datetime_deal(x))
  339. df['update_datetime'] = datetime.now(pytz.UTC).date()
  340. origin_columns = ['listing-id','seller_id',
  341. 'asin1','seller-sku','country_code',
  342. 'marketplace_id','quantity','fulfillment_channel',
  343. 'price','opendate','status','update_datetime','product-id','product-id-type'
  344. ]
  345. cursor = conn.cursor()
  346. cursor.execute("""select product_id,asin from (select * from ansjer_dvadmin.seller_listings where asin is not null
  347. and asin<>'' and product_id is not null and product_id <>'') t1 group by product_id,asin""")
  348. query_ = cursor.fetchall()
  349. col_name = [i[0] for i in cursor.description]
  350. df_datatable = pd.DataFrame(query_, columns=col_name)
  351. merged_df = df.merge(df_datatable[['product_id','asin']],how='left',left_on='product-id',right_on='product_id')
  352. print(merged_df.head())
  353. def func_(asin,asin1,product_id):
  354. if 'B0' in str(product_id):
  355. return str(product_id)
  356. if pd.isna(asin1) or asin1=='':
  357. return asin
  358. else:
  359. return asin1
  360. merged_df['asin1'] = merged_df.apply(lambda x:func_(x['asin'],x['asin1'],x['product-id']),axis=1) #x['asin'] if pd.isna(x['asin1']) or x['asin1']=='' else x['asin1']
  361. merged_df.fillna('',inplace=True)
  362. df1 = merged_df.copy()
  363. print(df1[origin_columns].head(1))
  364. update_df = self.update_data(df1,seller_id,str(self.marketplace)[-2:],conn)
  365. # update_df.to_csv("fr.csv")
  366. if len(update_df)==0:
  367. return '无更新数据插入'
  368. cursor = conn.cursor()
  369. try:
  370. insertsql = """insert into
  371. ansjer_dvadmin.seller_listings(listing_id,seller_id,asin,sku,country_code,marketplace_id,quantity,
  372. fulfillment_channel,price,launch_datetime,status,update_datetime,product_id,product_id_type)
  373. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  374. conn.begin()
  375. cursor.executemany(insertsql,tuple(update_df[origin_columns].to_numpy().tolist()))
  376. conn.commit()
  377. return '插入完成'
  378. except Exception as e:
  379. print("插入错误:",e)
  380. conn.rollback()
  381. return '出错回滚'
  382. @classmethod
  383. def get_allShops(cls):
  384. auth_conn = SpApiRequest.mysql_connect_auth()
  385. cursor = auth_conn.cursor()
  386. cursor.execute("select * from amazon_sp_report.amazon_sp_auth_info;")
  387. columns_name = [i[0] for i in cursor.description]
  388. rel = cursor.fetchall()
  389. df = pd.DataFrame(rel, columns=columns_name)
  390. for refresh_token in df['refresh_token'].to_numpy().tolist():
  391. aws_credentials = {
  392. 'refresh_token': refresh_token,
  393. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  394. 'lwa_client_secret': 'amzn1.oa2-cs.v1.3af0f5649f5b8e151cd5bd25c10f2bf3113172485cd6ffc52ccc6a5e8512b490',
  395. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  396. 'aws_secret_key': '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',
  397. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  398. }
  399. single_info = df.query("refresh_token==@refresh_token")
  400. region_circle = single_info['region'].values[0]
  401. seller_id = single_info['selling_partner_id'].values[0]
  402. account_name = single_info['account_name'].values[0]
  403. if region_circle == 'NA':
  404. pass
  405. for marketplace in [Marketplaces.US, Marketplaces.BR, Marketplaces.CA, Marketplaces.MX]:
  406. sp_api = SpApiRequest(aws_credentials, marketplace)
  407. try:
  408. sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  409. except Exception as e:
  410. print(e)
  411. elif region_circle == 'EU':
  412. pass
  413. for marketplace in [Marketplaces.DE,Marketplaces.AE, Marketplaces.BE, Marketplaces.PL,
  414. Marketplaces.EG,Marketplaces.ES, Marketplaces.GB, Marketplaces.IN, Marketplaces.IT,
  415. Marketplaces.NL, Marketplaces.SA, Marketplaces.SE, Marketplaces.TR,Marketplaces.UK,Marketplaces.FR,
  416. ]:
  417. sp_api = SpApiRequest(aws_credentials, marketplace)
  418. try:
  419. sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  420. except Exception as e:
  421. print(e)
  422. else:
  423. marketplace = eval(f'Marketplaces.{region_circle}')
  424. sp_api = SpApiRequest(aws_credentials, marketplace)
  425. sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  426. def timeDeal(self, orgTime):
  427. orgTime = parse(orgTime)
  428. timezone = pytz.timezone("UTC")
  429. shopTime = orgTime.astimezone(timezone)
  430. shopTime_datetime = datetime(shopTime.year, shopTime.month, shopTime.day, shopTime.hour, shopTime.minute,
  431. shopTime.second)
  432. return shopTime_datetime
  433. def GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(self,seller_id):
  434. # timezone_ = pytz.timezone(self.timezone)
  435. shopReportday = (datetime.now() + timedelta(days=-2)).strftime("%Y-%m-%d")
  436. # print(shopReportday)
  437. para = {"reportType":ReportType.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL,"dataStartTime":shopReportday,"dataEndTime":shopReportday,"reportOptions":{"ShowSalesChannel":"true"}}
  438. reportid = self.create_report(**para) #{"ShowSalesChannel":"true"}
  439. decom_df = self.decompression(reportid)
  440. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].fillna(0.0)
  441. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].fillna(0)
  442. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].astype('string')
  443. if "purchase-order-number" in decom_df.columns:
  444. decom_df['purchase-order-number'] = decom_df['purchase-order-number'].astype("string")
  445. decom_df.fillna('',inplace=True)
  446. # decom_df.to_csv('order.csv')
  447. decom_df["ReportDate"] = parse(shopReportday)
  448. decom_df['timezone'] = decom_df[["purchase-date"]].map(lambda x: parse(x).tzname()).fillna(method='bfill')
  449. decom_df[["purchase-date", "last-updated-date"]] = decom_df[["purchase-date", "last-updated-date"]].applymap(
  450. lambda x: self.timeDeal(x) if pd.isna(x) == False or x != None else x)
  451. decom_df['seller_id'] = seller_id
  452. list_df = decom_df.to_numpy().tolist()
  453. print(list_df[0])
  454. # tuple_data = [tuple(i) for i in list_df]
  455. conn = self.mysql_connect()
  456. cursor = conn.cursor()
  457. # print(list(conn.query("select * from amz_sp_api.orderReport")))
  458. sql = f"""
  459. insert into amz_sp_api.orderReport
  460. values (%s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s,%s)
  461. """ #ok
  462. # print(sql)
  463. try:
  464. conn.begin()
  465. cursor.executemany(sql,list_df)
  466. conn.commit()
  467. print("插入完成")
  468. except Exception as e:
  469. conn.rollback()
  470. print(e)
  471. if __name__ == '__main__':
  472. SpApiRequest.get_allShops()
  473. """
  474. create database amz_sp_api;
  475. """
  476. """
  477. create table amz_sp_api.productInfo
  478. (
  479. `item-name` VARCHAR(300),
  480. `item-description` VARCHAR(1000),
  481. `listing-id` VARCHAR(50),
  482. `seller-sku` VARCHAR(50),
  483. `price` FLOAT,
  484. `quantity` INT,
  485. `open-date` VARCHAR(70),
  486. `image-url` VARCHAR(300),
  487. `item-is-marketplace` VARCHAR(50),
  488. `product-id-type` INT,
  489. `item-note` VARCHAR(300),
  490. `item-condition` INT,
  491. `asin1` VARCHAR(50),
  492. `asin2` VARCHAR(50),
  493. `asin3` VARCHAR(50),
  494. `will-ship-internationally` VARCHAR(50),
  495. `expedited-shipping` VARCHAR(50),
  496. `product-id` VARCHAR(50),
  497. `bid-for-featured-placement` FLOAT,
  498. `add-delete` VARCHAR(50),
  499. `pending-quantity` INT,
  500. `fulfillment-channel` VARCHAR(50),
  501. `merchant-shipping-group` VARCHAR(50),
  502. `status` VARCHAR(50),
  503. `mainImageUrl` VARCHAR(300),
  504. `opendate_date` Date,
  505. `updateTime` Date,
  506. `timezone` VARCHAR(30)
  507. )
  508. """
  509. """
  510. create table amz_sp_api.orderReport
  511. (`amazon-order-id` VARCHAR(40),
  512. `merchant-order-id` VARCHAR(40),
  513. `purchase-date` DATETIME,
  514. `last-updated-date` DATETIME,
  515. `order-status` VARCHAR(40),
  516. `fulfillment-channel` VARCHAR(40),
  517. `sales-channel` VARCHAR(40),
  518. `order-channel` VARCHAR(40),
  519. `ship-service-level` VARCHAR(40),
  520. `product-name` VARCHAR(250),
  521. `sku` VARCHAR(50),
  522. `asin` VARCHAR(40),
  523. `item-status` VARCHAR(40),
  524. `quantity` INT,
  525. `currency` VARCHAR(40),
  526. `item-price` FLOAT,
  527. `item-tax` FLOAT,
  528. `shipping-price` FLOAT,
  529. `shipping-tax` FLOAT,
  530. `gift-wrap-price` FLOAT,
  531. `gift-wrap-tax` FLOAT,
  532. `item-promotion-discount` FLOAT,
  533. `ship-promotion-discount` FLOAT,
  534. `ship-city` VARCHAR(40),
  535. `ship-state` VARCHAR(40),
  536. `ship-postal-code` VARCHAR(40),
  537. `ship-country` VARCHAR(40),
  538. `promotion-ids` VARCHAR(50),
  539. `cpf` VARCHAR(40),
  540. `is-business-order` BOOL,
  541. `purchase-order-number` VARCHAR(50),
  542. `price-designation` VARCHAR(40),
  543. `signature-confirmation-recommended` BOOL,
  544. `ReportDate` DATE not null,
  545. `timezone` VARCHAR(20) not null
  546. );
  547. """