[Python] Issues in conversion of a specific string to dictionary [duplicate]

Discussão em 'Python' iniciado por Stack, Dezembro 9, 2024.

  1. Stack

    Stack Membro Participativo

    I'd like to convert a string into dict. The input string is taken from the database.

    Below is the log.before (this is the given string from the databse)given.

    {'id': '25c16650-070c-4e17-8996-f8d79d1747d7', 'tariff': OrderedDict([('id', 1), ('title', 'dTtvdvemDLYDHZiPNfaDwgAsTopnQBvYiHVPJvlREQaqLtlJFkQVFKZhpmWWphaxedqzWZBcpXxglKZvgpzPzPVEkSnJfEHnVfHy'), ('price', '0.00'), ('label', '(None) dTtvdvemDLYDHZiPNfaDwgAsTopnQBvYiHVPJvlREQaqLtlJFkQVFKZhpmWWphaxedqzWZBcpXxglKZvgpzPzPVEkSnJfEHnVfHy')]), 'title': 'Test Product', 'price': None, 'establishment': 0.0, 'billing_period': 'M', 'additional_points': [], 'speed_unit': 'Gb', 'service_type': 'P', 'type': 'S', 'show_with_vat': True, 'price_with_vat': 0, 'establishment_with_vat': 0, 'has_express_delivery': False, 'conversion_reporting_configs': [], 'index': 1, 'speed_up': 'None', 'speed_down': 'None'}


    In order to convert this string to dict, I've written like this.

    try:
    before = ast.literal_eval(log.before) if log.before else {}
    except Exception as e:
    print(e)


    And there's an error like this.

    malformed node or string: <ast.Call object at 0x7fb3b60d94f0>


    I think the problem is with the OrderedDict in the string given.

    Just for the record, below is the full code snippet.


    import csv
    import ast
    # import json
    # import re
    from collections import OrderedDict
    from io import StringIO

    from core.celery import app as celery_app
    from django.utils.timezone import now, timedelta
    from django.core.mail import EmailMessage
    from django.conf import settings

    from intern.apps.geo.models import GeoLog, GeoUpload, GeoUploadProcess
    from intern.apps.geo.processors import GeoFileProcessor

    @celery_app.task
    def generate_geo_manager_report(start_date=None, end_date=None):

    if start_date is None and end_date is None:
    end_date = now()
    start_date = end_date - timedelta(days=7)

    logs = GeoLog.objects.filter(when__range=[start_date, end_date])

    if not logs.exists():
    print("No logs found, exiting task.")
    return

    stats = {model: {action: 0 for action in GeoLog.Action.values} for model in GeoLog.ModelType.values}

    csv_files = {model: [] for model in GeoLog.ModelType.values}

    for log in logs:
    if log.model_type is None:
    print(f"Skipping log due to None model_type: {log}")
    continue
    print("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG")

    stats[log.model_type][log.action] += 1

    print(f"Raw before: {log.before}")
    print(f"Raw after: {log.after}")

    try:
    before = ast.literal_eval(log.before) if log.before else {}
    except Exception as e:
    print(e)

    try:
    after = ast.literal_eval(log.after) if log.after else {}
    except Exception as e:
    print(e)

    print(f"Serialized after: {before}")
    print(f"Serialized after: {after}")

    if log.action == 'update':
    changes = {
    key: (before[key], after[key]) if before.get(key) != after.get(key) else before[key]
    for key in set(before) | set(after)
    }
    else:
    changes = {**before, **after}

    # print(f"Serialized before: {before}")
    # print(f"Serialized after: {after}")

    csv_files[log.model_type].append({
    'changes': changes,
    'action': log.action,
    'when': log.when,
    'employee': log.employee.username if log.employee else 'System'
    })
    print("eeeeeeeeeeeeeeeeeeeeeeeeeeeee")
    print(f"Serialized csv_flies: {type(csv_files)}")

    attachments = []
    for model, rows in csv_files.items():
    if rows:
    output = StringIO()
    writer = csv.DictWriter(output, fieldnames=rows[0].keys())
    writer.writeheader()
    writer.writerows(rows)
    attachments.append((f"{model}.csv", output.getvalue()))

    subject = settings.GEO_MANAGER_REPORT_SUBJECT.format(
    start_date=start_date.strftime("%d/%m/%Y"),
    end_date=end_date.strftime("%d/%m/%Y"),
    )
    body = (
    f"Geo Manager Report for period {start_date.strftime('%d/%m/%Y')} to {end_date.strftime('%d/%m/%Y')}\n\n"
    + "\n".join(
    f"{sum(stats[model].values())} changes in {model} ({', '.join(f'{count} {action}' for action, count in actions.items() if count > 0)})"
    for model, actions in stats.items()
    )
    )
    print("Sending email...")
    email = EmailMessage(subject, body, to=settings.GEO_MANAGER_REPORT_RECIPIENTS)
    for filename, content in attachments:
    email.attach(filename, content, 'text/csv')
    email.send()

    Continue reading...

Compartilhe esta Página