The code that makes up the query builder I've been working on is pretty
extensive, so I'll go through the high-level basics.
I've set up a `_base` method that augments the SQLALchemy Base model. Note
the column details retrived in `get_column_and_json_key_from_sql_name` class
method:
class _base:
"""
This class augments the default SQLAlchemy Base model
"""
@classmethod
def get_column_and_json_key_from_sql_name(cls, name):
"""
Returns the column and, if applicable, the JSON top-level key from the
JSON dict.
:param name: Name of field.
:return:
"""
assert type(name) == str
json_key = None
col_names = name.split(COLUMN_NAME_DELIMITER)
if len(col_names) == 2:
name, json_key = col_names
try:
col = cls.__table__.c[name]
except KeyError:
log.error("Invalid column name: %s", name)
return None
return (getattr(cls, col.name), json_key)
We then have a `_build_column` method that essentially is responsible for
retrieving the details necessary to construct the column for the select
statement necessary for constructing the SQLAlchemy ORM query:
def _build_column(self):
field_name = self.db.get("column")
model = self._object.get("model")
column_type, column_key = self.db.get("type"), self.db.get("key")
select_column, json_key = model.get_column_and_json_key_from_sql_name(
field_name
)
select_column = self._construct_json_select_field(
column_type, select_column, json_key, column_key
)
return select_column
What I'm trying to figure out is how to dynamically generate SQLAlchemy ORM
statements based on the formula. The formulas can be any math equation
using +, -, /, *, and parentheses:
formula1 = '"metric:1" + "metric:2" + "metric:3"'
formula2 = '"metric:1" + "metric:2" - "metric:3"'
formula3 = '"metric:1" + ("metric:2" * "metric:3")'
formula4 = '"metric:1" / "metric:2"'
formula5 = '"metric:1 / ("metric:2" * "metric:3")'
The InstrumentedAttribute objects I mentioned earlier are the select fields
for each individual metric - what I need to figure out how to do is to be
able to build a SQLAlchemy ORM query by parsing the formula string, and
evaluating each operation in the context of the query. `func.sum` would
work for formula1, but I'd need to iteratively build the formula with
SQLAlchemy ORM helper methods for formula2 - formula5.
Per +Jonathan Vanasco's last comment, I've already figured out Phase 1. I'm
stuck on Phase 2.
On Thursday, March 28, 2019 at 4:43:56 PM UTC-4, Ian Miller wrote:
>
> Hello all,
>
> I am in the process of trying to create a dynamic expression query engine
> in an application I'm working on.
>
> So there is a formula that gets defined like so:
>
> formula = '"metric:123" + "metric:456" + "metric:789"'
>
> Each metric maps to a column in the database tables - long story short,
> I'm able to retrieve the metric by ID, and instantiate an
> InstrumentedAttribute object that has the SQLAlchemy metadata for the
> associated column. What I'm trying to achieve is to be able to iterate
> through the formula, and dynamically build a SQLALchemy query that maps to
> the formula.
>
> For example, the formula defined above would look something like this in
> SQL:
>
> SELECT post.id + campaign.id + asset.id
> FROM post, campaign, asset
> WHERE ......;
>
> The idea is to translate the above to something like:
>
> session.query(<sqlalchemy.orm.attributes.InstrumentedAttribute object at
> 0x7ff9269f92b0> + <sqlalchemy.orm.attributes.InstrumentedAttribute object
> at 0x7ff9269c5990> + <sqlalchemy.orm.attributes.InstrumentedAttribute
> object at 0x7ff926896048>).all()
>
> I've tried a couple of approaches of dynamically generating the SQLAlchemy
> ORM query, but I haven't been able to find anything that works. Would
> anyone have any idea or tips on how to accomplish this?
>
> Thank you!
>
>
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.