News for hackers. Stuff that matters.
Re:Bye Bye Mongo, Hello Postgres by aidos on Wednesday December 19, 2018 @06:08PM (#18720813)
I’ll try to avoid a flame war, but since you’re using python, SQLAlchemy allows for composing sql strings.
Re:Bye Bye Mongo, Hello Postgres by raverbashing on Wednesday December 19, 2018 @06:11PM (#18720840)
Yes, an ORM, not SQL itself.
Re:Bye Bye Mongo, Hello Postgres by walrus1066 on Wednesday December 19, 2018 @06:39PM (#18721075)
You can compose queries, using the queryAPI in SQLAlchemy, without touching the ORM.
Re:Bye Bye Mongo, Hello Postgres by zrail on Wednesday December 19, 2018 @06:39PM (#18721071)
SQLAlchemy is not an ORM. There’s a companion ORM project if you want it, but it’s not necessary.
Re:Bye Bye Mongo, Hello Postgres by yawaramin on Wednesday December 19, 2018 @06:31PM (#18721005)
Yes? What's the qualitative difference between using a best-of-breed SQL ORM and the Mongo API?
Re:Bye Bye Mongo, Hello Postgres by quietbritishjim on Wednesday December 19, 2018 @07:24PM (#18721372)
For it to replace MongoDB's aggregation pipeline, it would need to play nicely with JSONB. Does it do that? This is the thing I'm really missing.

For example, if documents in the JSONB column all look roughly like this:

    {
        "someArrayField": [
            { "key": "steve", "value": 7 },
            { "key": "bob", "value": 15 },
        ],
        "someOtherField": [ "whatever" ]
    }

* Can I count the number of entries in someArrayField, summed across all records?

* Can I get the per-record mean of the "value" sub-field, summed across all records?

* Can I filter by records that have a "someArrayField" entry where "key" is "steve" and "value" is at least 10 (the above record should NOT match)?

Re:Bye Bye Mongo, Hello Postgres by luhn on Wednesday December 19, 2018 @08:14PM (#18721686)
Yes, you can!

The jsonb_array_elements function is roughly similar to Mongo’s $unwind pipeline op. It explodes a JSON array into a set of rows. From there it’s pretty simple aggregates to achieve what you’re looking for.

I was evaluating Mongo a couple months back to solve roughly the same problems. Eventually discovered Postgres already had what I was looking for.

Re:Bye Bye Mongo, Hello Postgres by inferiorhuman on Wednesday December 19, 2018 @09:04PM (#18721933)
More the point Postgres has an actual array data type (and has for a while). You don't need to shove everything into a JSON/JSONB blob unless you absolutely cannot have any sort of schema.
Re:Bye Bye Mongo, Hello Postgres by zaarn on Thursday December 20, 2018 @02:29AM (#18723098)
Not only arrays, you can, with some limitations, create proper types with field names, if your ORM supports that you should use that over JSONB if it fits.
Re:Bye Bye Mongo, Hello Postgres by inferiorhuman on Thursday December 20, 2018 @02:31AM (#18723107)
See also: PostGIS.
Re:Bye Bye Mongo, Hello Postgres by quietbritishjim on Wednesday December 19, 2018 @09:43PM (#18722081)
Allow me to restate this question:

> Does it do that?

It was supposed to be clear from the context that this meant:

> Does building queries programmatically with SQLAlchemy do that?

Maybe I'm misreading your comment, but you seem to just be talking about writing queries directly in SQL.

If not, could you give an example/link of how to programmically build a query in SQLAlchemy that dynamically makes use of jsonb_array_elements? It would be hugely useful if I could do that.

Re:Bye Bye Mongo, Hello Postgres by simonw on Thursday December 20, 2018 @12:15AM (#18722671)
There are some old examples of how to use jsonb_array_elemens in SQLAlchemy here: https://github.com/sqlalchemy/sqlalchemy/issues/3566#issueco...
Re:Bye Bye Mongo, Hello Postgres by luhn on Thursday December 20, 2018 @03:12AM (#18723265)
I was speaking of SQL, but if you can write it in SQL you can usually map it to SQLAlchemy. If worse comes to worse, you can use text() to drop down to raw SQL for just a portion of the query.

SQLAlchemy’s Postgres JSONB type allows subscription, so you can do Model.col[‘arrayfield’]. You can also manually invoke the operator with Model.col.op(‘->’)(‘arrayfield’).

So you should be able to do something like:

func.sum(func.jsonb_array_elements(Model.col.op(‘->’)(‘arrayfield’)).op(‘->’)(‘val’))

(Writing on my mobile without reference, so may not be fully accurate)

Re:Bye Bye Mongo, Hello Postgres by ris on Thursday December 20, 2018 @12:16PM (#18726827)
It absolutely can, but in my experience, 99% of the time, choosing to make a data field JSON/JSONB ends up being a mistake.