def test_build_resonance(input_values: List[str], asteroid_num: int, asteroid_indicies: List[int], planets: Tuple[str], resonancesfixture): factory = get_resonance_factory(planets, input_values, asteroid_num) build_resonance(factory) planet_q = session.query(Planet) asteroid_q = session.query(Asteroid) body_count = BodyNumberEnum(len(planets) + 1) resonances_q = _build_resonances_query(body_count, input_values, asteroid_num, factory) def _check_bodies(): """ check values of entities from database with input values. :return: """ resonances = resonances_q.all() assert len(resonances) == 1 db_planets = planet_q.all() # type: List[Planet] assert len(db_planets) == body_count.value - 1 for planet, foreign in zip(db_planets, BODY_FOREIGNS): _check(planet, factory.bodies[foreign]) assert getattr(resonances[0], foreign) == planet asteroids = asteroid_q.all() # type: List[Asteroid] _check(asteroids[0], {'name': 'A%i' % asteroid_num, LONG_COEFF: int(input_values[asteroid_indicies[0]]), PERI_COEFF: int(input_values[asteroid_indicies[1]])}) assert asteroids[0].axis == float(input_values[asteroid_indicies[2]]) assert len(asteroids) == 1 assert resonances[0].small_body == asteroids[0] _check_bodies() build_resonance(factory) _check_bodies()
def get_planets(self) -> Query: cols = [ PLANET_TABLES[x].name.label('%s_name1' % x) for x in self._foreings ] query = session.query(*cols).select_from(self.resonance_cls) query = self._add_join(query).group_by(*cols) return query
def _build_resonances_query(body_number: BodyNumberEnum, input_values: List[str], asteroid_num: int, factory: ResonanceFactory) -> Query: planet_tables = [aliased(Planet) for _ in range(body_number.value - 1)] resonance_cls = factory.resonance_cls resonances_q = session.query(resonance_cls) for planet_table, body_foreign in zip(planet_tables, BODY_FOREIGNS): resonances_q = resonances_q \ .join(planet_table, getattr(resonance_cls, body_foreign)) \ .options(joinedload(body_foreign)) and_args = [] for planet_table, body_foreign in zip(planet_tables, BODY_FOREIGNS): body_data = factory.bodies[body_foreign] and_args.append(planet_table.longitude_coeff == body_data[LONG_COEFF]) and_args.append(planet_table.perihelion_longitude_coeff == body_data[PERI_COEFF]) body_data = factory.bodies['small_body'] and_args += [ Asteroid.longitude_coeff == body_data[LONG_COEFF], Asteroid.perihelion_longitude_coeff == body_data[PERI_COEFF], Asteroid.axis == body_data['axis'], ] resonances_q.join(resonance_cls.small_body).options(joinedload('small_body')) \ .filter(and_(*and_args)) return resonances_q
def _is_resonance_exists(self, conn) -> Tuple[bool, Select]: with warnings.catch_warnings(): warnings.simplefilter("ignore", category=sa_exc.SAWarning) _build_planets(conn, self._get_planets(), self._get_asteroid()) body_clause = and_(*[_make_sql_condition(y.c, self.bodies[x]) for x, y in self._body_tables.items()]) sel = select([x.c.id for x in self._body_tables.values()]).where(body_clause) resonance_exists = False if not _is_support_upsert(): subquery = session.query(self._resonance_cls) for key, value in self._body_tables.items(): subquery = subquery.join(value, getattr(self._resonance_cls, key)) resonance_exists = session.query(subquery.filter(body_clause).exists()).scalar() return resonance_exists, sel
def __init__(self, for_bodies: BodyNumberEnum, load_related=False): self._load_related = load_related if for_bodies == BodyNumberEnum.three: self.resonance_cls = ThreeBodyResonance else: self.resonance_cls = TwoBodyResonance self.query = session.query(self.resonance_cls) self.for_bodies = for_bodies self._foreings = FOREIGNS[:for_bodies.value - 1] self._asteroid_alias = aliased(Asteroid)
def resonance_fixture_different_librations(request): asteroid_nums = 1, 211, 78 planets = request.param['planets'] line_data_set = request.param['line_data_set'] fixture_base(asteroid_nums, (planets,), line_data_set) request.addfinalizer(clear_resonance_finalizer) cls = ThreeBodyResonance if len(planets) == 2 else TwoBodyResonance libration_cls = Libration if len(planets) == 2 else TwoBodyLibration resonance = session.query(cls).outerjoin(Asteroid).filter( Asteroid.number == asteroid_nums[0]).first() libration = libration_cls(resonance, [], 0, False) session.commit() return asteroid_nums, planets, libration
def test_id_sequences_errors(line_data: List[str], next_line_data: List[str], planets: List[Tuple], test_table: Table, _constraint_fixture): resonance_factory = get_resonance_factory(planets[0], line_data, 1) build_resonance(resonance_factory) conn = engine.connect() conn.execute('ALTER SEQUENCE %s_id_seq RESTART WITH 1;' % test_table.name) resonance_factory = get_resonance_factory(planets[1], next_line_data, 1) build_resonance(resonance_factory) for i, entry in enumerate(session.query(test_table).all()): assert (i + 1) == entry.id
def get_resonance_query(for_bodies: BodyNumberEnum) -> Query: """ Make select query for getting two or three body resonances. :param for_bodies: is need for pointing the type of resonances. :return: """ if for_bodies == BodyNumberEnum.three: resonance_cls = ThreeBodyResonance else: resonance_cls = TwoBodyResonance query = session.query(resonance_cls) \ .options(joinedload('small_body')).join(resonance_cls.small_body) for i, key in enumerate(FOREIGNS): if i >= (for_bodies.value - 1): break planet_table = PLANET_TABLES[key] resonance_attr = getattr(resonance_cls, '%s_id' % key) query = query.join(planet_table, resonance_attr == planet_table.id) \ .options(joinedload(key)) return query
def show_broken_bodies(): items = session.query(BrokenAsteroid).order_by(BrokenAsteroid.name).all() for item in items: print(item.name)
def check(self): with session.no_autoflush: query = exists().where(BrokenAsteroid.name == self._asteroid_name) return session.query(query).scalar()
def test_three_body_resonance_count(line_data: List[str], next_line_data: List[str], planets: List[Tuple], resonance_count: int, _constraint_fixture): _create_two_resonances(line_data, next_line_data, planets) assert session.query(ThreeBodyResonance).count() == resonance_count
def test_planet_count(line_data: List[str], next_line_data: List[str], planets: List[Tuple], planet_count: int, _constraint_fixture): _create_two_resonances(line_data, next_line_data, planets) assert session.query(Planet).count() == planet_count