简体   繁体   中英

How can I remove additional backslashes in json output using json.dumps in SQLAlchemy & FastAPI?

Ok so I have my classes set up like this:

class ToDictMixin(object):
    def to_dict(self, camelcase=True):
        if camelcase:
            return {to_camelcase(column.key): getattr(self, attr) for attr, column in self.__mapper__.c.items()}
        else:
            return {column.key: getattr(self, attr) for attr, column in self.__mapper__.c.items()}


class Company(Base, ToDictMixin):
    __tablename__ = 'companies'

    number = Column(Integer, primary_key=True)
    name = Column(String)
    incorporated = Column(Date)

I also have these functions:

def to_camelcase(s):
    return re.sub(r'(?!^)_([a-zA-Z])', lambda m: m.group(1).upper(), s)


def alchemyencoder(obj):
    """
    JSON encoder function for SQLAlchemy special classes.
    """

    if isinstance(obj, datetime.date):
        return obj.isoformat()
    elif isinstance(obj, decimal.Decimal):
        return float(obj)


def to_json(self, rel=None):
    return json.dumps(self.to_dict(), default=alchemyencoder)

And in my FastAPI file I do the following:

@app.get("/testrequest")
def test_request():
    query = SESSION.query(Company).order_by(Company.number).filter_by(name="PAARTI LTD")
    return {"company": to_json(i) for i in query}

Before loading this page I tested the following in the python console:

>>> query = SESSION.query(Company).order_by(Company.number).filter_by(name="PAARTI LTD")
>>> a = query[0]
>>> a.to_dict()
{'created': datetime.datetime(2020, 5, 7, 13, 10, 5), 'number': 12585493, 'name': 'PAARTI LTD', 'incorporated': datetime.date(2020, 5, 5)}
>>> to_json(a)
'{"created": "2020-05-07T13:10:05", "number": 12585493, "name": "PAARTI LTD", "incorporated": "2020-05-05"}'

Which looks right to me. This is exactly how I want it to be displayed.

However when testing http://127.0.0.1:8000/testrequest in my browser I get the following:

{"company":"{\"created\": \"2020-05-07T13:10:05\", \"number\": 12585493, \"name\": \"PAARTI LTD\", \"incorporated\": \"2020-05-05\"}"}

I don't understand why it is trying to escape these backslashes in the web response. How can I fix this to have a proper json response of just the following:

{"company":{"created": "2020-05-07T13:10:05", "number": 12585493, "name": "PAARTI LTD", "incorporated": "2020-05-05"}}

Try this, build the dictionary first, then dump to json at once.

@app.get("/testrequest") def test_request(): query = SESSION.query(Company).order_by(Company.number).filter_by(name="PAARTI LTD") return json.dumps({"company": i.to_dict() for i in query}, default=alchemyencoder)

import json

@app.get("/testrequest")
def test_request():
    query = SESSION.query(Company).order_by(Company.number).filter_by(name="PAARTI LTD")
    return {"company": json.loads(to_json(i) for i in query)}

Just use json.loads(str)

You can just return the JSON like that:

        @router.get('/statistics')
        async def get_statistics():
            return self.json_data

For me, it works like a charm

{
    "CLIENT": [
        {
            "topics": [
                "topic"
            ],
        }
    ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM