pythonjsondjangodjango-fixtures

How to generate one json into two json?


I have the following fixture from a Django project:

[
{
  "model": "music",
  "pk": 1,
  "fields": {
    "attributed_to": false,
    "creator": null,
    "name": "Piano Trio No. 1",
    "name_en": "Piano Trio No. 1",
    "name_de": "Trios für Pianoforte, Violine und Violoncello, Nr. 1",
    "dedicated_to": "Prince Karl Lichnowsky",
    "piece_type": "Trio",
    "category": "Chamber Music",
    "date_start": "1792-01-01",
    "date_completed": "1794-01-01",
    "key": "e-flat major"
},
{
  "model": "music",
  "pk": 2,
  "fields": {
    "attributed_to": false,
    "creator": null,
    "name": "Piano Trio No. 2",
    "name_en": "Piano Trio No. 2",
    "name_de": "Trios für Pianoforte, Violine und Violoncello, Nr. 2",
    "dedicated_to": "Prince Karl Lichnowsky",
    "piece_type": "Trio",
    "category": "Chamber Music",
    "date_start": "1792-01-01",
    "date_completed": "1794-01-01",
    "key": "G major"
},
{
  "model": "music",
  "pk": 3,
  "fields": {
    "attributed_to": false,
    "creator": null,
    "name": "Piano Trio No. 3",
    "name_en": "Piano Trio No. 3",
    "name_de": "Trios für Pianoforte, Violine und Violoncello, Nr. 3",
    "dedicated_to": "Prince Karl Lichnowsky",
    "piece_type": "Trio",
    "category": "Chamber Music",
    "date_start": "1792-01-01",
    "date_completed": "1794-01-01",
    "key": "c minor"
}
]

Due to a restructure of the app, I need to spilt/sort various columns of this fixture/json into two separate fixture/jsons. The two new fixture/json files should look like this:

Fixture #1

[
{
  "model": "music",
  "pk": 1,
  "fields": {
    "creator": null,
    "name": "Piano Trio No. 1",
    "name_en": "Piano Trio No. 1",
    "name_de": "Trios für Pianoforte, Violine und Violoncello, Nr. 1",
    "key": "e-flat major"
},
{
  "model": "music",
  "pk": 2,
  "fields": {
    "creator": null,
    "name": "Piano Trio No. 2",
    "name_en": "Piano Trio No. 2",
    "name_de": "Trios für Pianoforte, Violine und Violoncello, Nr. 2",
    "key": "G major"
},
{
  "model": "music",
  "pk": 3,
  "fields": {
    "creator": null,
    "name": "Piano Trio No. 3",
    "name_en": "Piano Trio No. 3",
    "name_de": "Trios für Pianoforte, Violine und Violoncello, Nr. 3",
    "key": "c minor"
}
]

Fixture #2

[
{
  "model": "meta",
  "pk": 1,
  "fields": {
    "attributed_to": false,
    "dedicated_to": "Prince Karl Lichnowsky",
    "piece_type": "Trio",
    "category": "Chamber Music",
    "date_start": "1792-01-01",
    "date_completed": "1794-01-01",
},
{
  "model": "meta",
  "pk": 2,
  "fields": {
    "attributed_to": false,
    "dedicated_to": "Prince Karl Lichnowsky",
    "piece_type": "Trio",
    "category": "Chamber Music",
    "date_start": "1792-01-01",
    "date_completed": "1794-01-01",
},
{
  "model": "meta",
  "pk": 3,
  "fields": {
    "attributed_to": false,
    "dedicated_to": "Prince Karl Lichnowsky",
    "piece_type": "Trio",
    "category": "Chamber Music",
    "date_start": "1792-01-01",
    "date_completed": "1794-01-01",
}
]

I was wondering if there is an easy with python either through some sort of string manipulation or Json library to take the source file and generate/output these two new fixtures/json.

Cheers.


Solution

  • A simple way might be to first define a dictionary that will, for each new model, define the fields to work with:

    mapping = {
        'music': ['creator', 'name', 'name_en', 'name_de', 'key'],
        'meta': [
            'attributed_to',
            'dedicated_to',
            'piece_type',
            'category',
            'date_start',
            'date_completed',
        ],
    }

    then we thus read the in-file and make two new outfiles:

    with open('infile.json', 'r') as f:
        data = json.load(f)
    
    for model, columns in mapping.items():
        sub_data = [
            {
                'model': model,
                'pk': entry['pk'],
                'fields': {column: entry['fields'][column] for column in columns},
            }
            for entry in data
        ]
        with open(f'{model}.json', 'w') as f:
            json.dump(sub_data, f)

    This will then process a file named infile.json as fixture, and will in this case produce two files music.json and meta.json.