fluent-kit icon indicating copy to clipboard operation
fluent-kit copied to clipboard

Valor (fluent?) cant decode an array directly from the DB

Open patchthecode opened this issue 4 years ago • 7 comments

So this is my original code

extension DiscoverController {
    struct TrendingHashtagsOutput: Content {
        let trending_hashes: [String]
    }
    
    func trendingHashTag(req: Request) throws -> EventLoopFuture<TrendingHashtagsOutput> {
        guard let pgdb = req.db as? PostgresDatabase else { throw Abort(.internalServerError) }
        let query =
        """
        \(baseCacheSql),
        \(trendingHashtagSql)
        select jsonb_agg(tag) trending_hashes from trending_hashtags
        """
        return  try pgdb.sql()
            .raw(SQLQueryString(query))
            .requireFirst(decoding: TrendingHashtagsOutput.self, error: Abort(.notFound))
    }
}

Which fails to decode with this [ WARNING ] Value of type 'Array<String>' required for key ''. because my query returned results like this Screen_Shot_2021-11-26_at_4 10 21_PM

.. But after i changed my code to this

extension DiscoverController {
    struct TrendingHashtagsOutput2: Content {
        let trending_hashes: [String: [String]]
    }
    
    func trendingHashTag(req: Request) throws -> EventLoopFuture<TrendingHashtagsOutput2> {
        guard let pgdb = req.db as? PostgresDatabase else { throw Abort(.internalServerError) }
        let query =
        """
        \(baseCacheSql),
        \(trendingHashtagSql)
        select json_build_object('tag', jsonb_agg(tag)) trending_hashes from trending_hashtags
        """
        return  try pgdb.sql()
            .raw(SQLQueryString(query))
            .requireFirst(decoding: TrendingHashtagsOutput2.self, error: Abort(.notFound))

    }
}

it decodes correctly because the new query results looks like this. (i basically added a tag key) Screen_Shot_2021-11-26_at_4 13 11_PM

It appears as if Vapor is looking for key value pairs to decode and not plain arrays.

patchthecode avatar Nov 27 '21 15:11 patchthecode

@patchthecode Could you show your schema definition for this table?

mkll avatar Dec 20 '21 11:12 mkll

@patchthecode Is the problem is gone? Maybe we should close the issue?

mkll avatar Jan 18 '22 11:01 mkll

I dont think problem is gone. but... i did a work around, and i am too tied up in coding right now to leave an example. If im the only one experiencing this then i guess i can close it.

patchthecode avatar Jan 18 '22 22:01 patchthecode

@patchthecode Well, I asked you about a schema just because you didn't tell how that field specified in schema. Based on indirect information, I can assume that the .dictionary specified in your schema for that field. If this a case then you should change it to .array and the problem should gone (but I'm unsure).

mkll avatar Jan 19 '22 01:01 mkll

Oh no. my schema is a regular table. I used a very long query to to make by result become an array. json_agg i think it was?

the thing is, whenever the query result is an array, i cannot decode it. Only after changing it to a dictionary it worked.

patchthecode avatar Jan 19 '22 04:01 patchthecode

@patchthecode Oh, it seems I was completely wrong recognizing the problem. My bad.

mkll avatar Jan 19 '22 17:01 mkll

If you change the query to

let query =
        """
        \(baseCacheSql),
        \(trendingHashtagSql)
        select array_agg(tag) trending_hashes from trending_hashtags
        """

does it work?

0xTim avatar Jan 26 '22 15:01 0xTim