Cleaned up the directories

This commit is contained in:
ComputerTech312 2024-02-19 15:34:25 +01:00
parent f708506d68
commit a683fcffea
1340 changed files with 554582 additions and 6840 deletions

View file

@ -0,0 +1,128 @@
import sqlalchemy as sa
import sqlalchemy.orm
from sqlalchemy.sql.util import ClauseAdapter
from ..compat import _select_args
from .chained_join import chained_join # noqa
def path_to_relationships(path, cls):
relationships = []
for path_name in path.split('.'):
rel = getattr(cls, path_name)
relationships.append(rel)
cls = rel.mapper.class_
return relationships
def adapt_expr(expr, *selectables):
for selectable in selectables:
expr = ClauseAdapter(selectable).traverse(expr)
return expr
def inverse_join(selectable, left_alias, right_alias, relationship):
if relationship.property.secondary is not None:
secondary_alias = sa.alias(relationship.property.secondary)
return selectable.join(
secondary_alias,
adapt_expr(
relationship.property.secondaryjoin,
sa.inspect(left_alias).selectable,
secondary_alias
)
).join(
right_alias,
adapt_expr(
relationship.property.primaryjoin,
sa.inspect(right_alias).selectable,
secondary_alias
)
)
else:
join = sa.orm.join(right_alias, left_alias, relationship)
onclause = join.onclause
return selectable.join(right_alias, onclause)
def relationship_to_correlation(relationship, alias):
if relationship.property.secondary is not None:
return adapt_expr(
relationship.property.primaryjoin,
alias,
)
else:
return sa.orm.join(
relationship.parent,
alias,
relationship
).onclause
def chained_inverse_join(relationships, leaf_model):
selectable = sa.inspect(leaf_model).selectable
aliases = [leaf_model]
for index, relationship in enumerate(relationships[1:]):
aliases.append(sa.orm.aliased(relationship.mapper.class_))
selectable = inverse_join(
selectable,
aliases[index],
aliases[index + 1],
relationships[index]
)
if relationships[-1].property.secondary is not None:
secondary_alias = sa.alias(relationships[-1].property.secondary)
selectable = selectable.join(
secondary_alias,
adapt_expr(
relationships[-1].property.secondaryjoin,
secondary_alias,
sa.inspect(aliases[-1]).selectable
)
)
aliases.append(secondary_alias)
return selectable, aliases
def select_correlated_expression(
root_model,
expr,
path,
leaf_model,
from_obj=None,
order_by=None,
correlate=True
):
relationships = list(reversed(path_to_relationships(path, root_model)))
query = sa.select(*_select_args(expr))
join_expr, aliases = chained_inverse_join(relationships, leaf_model)
if order_by:
query = query.order_by(
*[
adapt_expr(
o,
*(sa.inspect(alias).selectable for alias in aliases)
)
for o in order_by
]
)
condition = relationship_to_correlation(
relationships[-1],
aliases[-1]
)
if from_obj is not None:
condition = adapt_expr(condition, from_obj)
query = query.select_from(join_expr.selectable)
if correlate:
query = query.correlate(
from_obj if from_obj is not None else root_model
)
return query.where(condition)

View file

@ -0,0 +1,31 @@
def chained_join(*relationships):
"""
Return a chained Join object for given relationships.
"""
property_ = relationships[0].property
if property_.secondary is not None:
from_ = property_.secondary.join(
property_.mapper.class_.__table__,
property_.secondaryjoin
)
else:
from_ = property_.mapper.class_.__table__
for relationship in relationships[1:]:
prop = relationship.property
if prop.secondary is not None:
from_ = from_.join(
prop.secondary,
prop.primaryjoin
)
from_ = from_.join(
prop.mapper.class_,
prop.secondaryjoin
)
else:
from_ = from_.join(
prop.mapper.class_,
prop.primaryjoin
)
return from_