Как упоминалось в предыдущих ответах, трудность преобразования json в csv заключается в том, что json-файл может содержать вложенные словари и, следовательно, быть многомерной структурой данных, а csv представляет собой структуру данных 2D. Однако хороший способ превратить многомерную структуру в csv состоит в том, чтобы иметь несколько csvs, которые объединяются с первичными ключами.
В вашем примере первый вывод csv имеет столбцы «pk», «model», , "поля" в качестве столбцов. Значения для «pk» и «model» легко получить, но поскольку столбец «поля» содержит словарь, он должен быть его собственным csv, и поскольку «кодовое имя» появляется как первичный ключ, вы можете использовать его как вход для «полей» для завершения первого сеанса. Второй csv содержит словарь из столбца «поля» с кодовым именем в качестве первичного ключа, который можно использовать для связывания двух csvs вместе.
Вот решение для вашего json-файла, который преобразует вложенные словари до 2 csvs.
import csv
import json
def readAndWrite(inputFileName, primaryKey=""):
input = open(inputFileName+".json")
data = json.load(input)
input.close()
header = set()
if primaryKey != "":
outputFileName = inputFileName+"-"+primaryKey
if inputFileName == "data":
for i in data:
for j in i["fields"].keys():
if j not in header:
header.add(j)
else:
outputFileName = inputFileName
for i in data:
for j in i.keys():
if j not in header:
header.add(j)
with open(outputFileName+".csv", 'wb') as output_file:
fieldnames = list(header)
writer = csv.DictWriter(output_file, fieldnames, delimiter=',', quotechar='"')
writer.writeheader()
for x in data:
row_value = {}
if primaryKey == "":
for y in x.keys():
yValue = x.get(y)
if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
row_value[y] = str(yValue).encode('utf8')
elif type(yValue) != dict:
row_value[y] = yValue.encode('utf8')
else:
if inputFileName == "data":
row_value[y] = yValue["codename"].encode('utf8')
readAndWrite(inputFileName, primaryKey="codename")
writer.writerow(row_value)
elif primaryKey == "codename":
for y in x["fields"].keys():
yValue = x["fields"].get(y)
if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
row_value[y] = str(yValue).encode('utf8')
elif type(yValue) != dict:
row_value[y] = yValue.encode('utf8')
writer.writerow(row_value)
readAndWrite("data")
Вы пробовали API коллекций проектов ?
Пример запроса:
GET https://mytfsserver/DefaultCollection/_apis/projectCollections/d81542e4-cdfa-4333-b082-1ae2d6c3ad16?api-version=1.0-preview.2
Пример ответа:
{
"id": "d81542e4-cdfa-4333-b082-1ae2d6c3ad16",
"name": "DefaultCollection",
"url": "https://mytfsserver/DefaultCollection/_apis/projectCollections/d81542e4-cdfa-4333-b082-1ae2d6c3ad16",
"state": "Started",
"_links": {
"self": {
"href": "https://mytfsserver/DefaultCollection/_apis/projectCollections/d81542e4-cdfa-4333-b082-1ae2d6c3ad16"
},
"web": {
"href": "https://mytfsserver/DefaultCollection"
}
}
}
Существует также ссылка на некоторый пример кода C #.
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;
namespace Microsoft.TeamServices.Samples.Client.ProjectsAndTeams
{
[ClientSample(CoreConstants.AreaName, CoreConstants.ProjectCollectionsResource)]
public class ProjectCollectionsSample : ClientSample
{
[ClientSampleMethod]
public IEnumerable<TeamProjectCollectionReference> ListProjectCollections()
{
VssConnection connection = Context.Connection;
ProjectCollectionHttpClient projectCollectionClient = connection.GetClient<ProjectCollectionHttpClient>();
IEnumerable<TeamProjectCollectionReference> projectCollections = projectCollectionClient.GetProjectCollections().Result;
foreach(var collection in projectCollections)
{
Console.WriteLine(collection.Name);
}
return projectCollections;
}
}
}