This commit is contained in:
Lucas Verney 2018-01-19 17:07:49 +01:00
parent ba40f71aed
commit 98ae12d10d
3 changed files with 53 additions and 14 deletions

View File

@ -13,7 +13,12 @@ from sqlalchemy.engine import Engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import OperationalError, SQLAlchemyError from sqlalchemy.exc import OperationalError, SQLAlchemyError
# Import models
import flatisfy.models.postal_code # noqa: F401
import flatisfy.models.public_transport # noqa: F401
import flatisfy.models.flat # noqa: F401 import flatisfy.models.flat # noqa: F401
import flatisfy.models.constraint # noqa: F401
from flatisfy.database.base import BASE from flatisfy.database.base import BASE
from flatisfy.database.whooshalchemy import IndexService from flatisfy.database.whooshalchemy import IndexService

View File

@ -7,8 +7,9 @@ from __future__ import absolute_import, print_function, unicode_literals
import logging import logging
from sqlalchemy import ( from sqlalchemy import (
Column, Float, Integer, String Column, Float, ForeignKey, Integer, String, Table
) )
from sqlalchemy.orm import relationship
from sqlalchemy_utils.types.json import JSONType from sqlalchemy_utils.types.json import JSONType
from sqlalchemy_utils.types.scalar_list import ScalarListType from sqlalchemy_utils.types.scalar_list import ScalarListType
@ -42,6 +43,13 @@ class PostTypes(enum.Enum):
SHARING = 2 SHARING = 2
association_table = Table(
'constraint_postal_codes_association', BASE.metadata,
Column('constraint_id', Integer, ForeignKey('constraints.id')),
Column('postal_code_id', Integer, ForeignKey('postal_codes.id'))
)
class Constraint(BASE): class Constraint(BASE):
""" """
SQLAlchemy ORM model to store a search constraint. SQLAlchemy ORM model to store a search constraint.
@ -52,18 +60,28 @@ class Constraint(BASE):
name = Column(String) name = Column(String)
type = Column(EnumListType(PostTypes, int)) type = Column(EnumListType(PostTypes, int))
house_types = Column(EnumListType(HouseTypes, int)) house_types = Column(EnumListType(HouseTypes, int))
postal_codes = Column(ScalarListType()) # TODO # TODO: What happens when one delete a postal code?
postal_codes = relationship("PostalCode", secondary=association_table)
area_min = Column(Float, default=None) # in m^2 area_min = Column(Float, default=None) # in m^2
area_max = Column(Float, default=None) # in m^2 area_max = Column(Float, default=None) # in m^2
cost_min = Column(Float, default=None) # in currency unit cost_min = Column(Float, default=None) # in currency unit
cost_max = Column(Float, default=None) # in currency unit cost_max = Column(Float, default=None) # in currency unit
rooms_min = Column(Integer, default=None) rooms_min = Column(Integer, default=None)
rooms_max = Column(Integer, default=None) rooms_max = Column(Integer, default=None)
bedrooms_min = Column(Integer, default=None) bedrooms_min = Column(Integer, default=None)
bedrooms_max = Column(Integer, default=None) bedrooms_max = Column(Integer, default=None)
minimum_nb_photos = Column(Integer, default=None) minimum_nb_photos = Column(Integer, default=None)
description_should_contain = Column(ScalarListType()) # list of terms description_should_contain = Column(ScalarListType()) # list of terms
time_to = Column(JSONType) # TODO
# Dict mapping names to {"gps": [lat, lng], "time": (min, max) }
# ``min`` and ``max`` are in seconds and can be ``null``.
# TODO: Use an additional time_to_places table?
time_to = Column(JSONType)
def __repr__(self): def __repr__(self):
return "<Constraint(id=%s, name=%s)>" % (self.id, self.name) return "<Constraint(id=%s, name=%s)>" % (self.id, self.name)

View File

@ -8,12 +8,11 @@ from __future__ import absolute_import, print_function, unicode_literals
import logging import logging
import enum import enum
import arrow
from sqlalchemy import ( from sqlalchemy import (
Column, Enum, Float, SmallInteger, String, Text, inspect Column, Enum, Float, ForeignKey, Integer, SmallInteger, String, Table,
Text, inspect
) )
from sqlalchemy.orm import validates from sqlalchemy.orm import relationship, validates
from sqlalchemy_utils.types.arrow import ArrowType from sqlalchemy_utils.types.arrow import ArrowType
from sqlalchemy_utils.types.json import JSONType from sqlalchemy_utils.types.json import JSONType
from sqlalchemy_utils.types.scalar_list import ScalarListType from sqlalchemy_utils.types.scalar_list import ScalarListType
@ -55,6 +54,14 @@ AUTOMATED_STATUSES = [
FlatStatus.ignored FlatStatus.ignored
] ]
stations_association_table = Table(
'stations_flats_association', BASE.metadata,
Column(
'public_transport_id', Integer, ForeignKey('public_transports.id')
),
Column('flat_id', Integer, ForeignKey('flats.id'))
)
class Flat(BASE): class Flat(BASE):
""" """
@ -72,7 +79,7 @@ class Flat(BASE):
cost = Column(Float) cost = Column(Float)
currency = Column(String) currency = Column(String)
utilities = Column(Enum(FlatUtilities), default=FlatUtilities.unknown) utilities = Column(Enum(FlatUtilities), default=FlatUtilities.unknown)
date = Column(ArrowDate) date = Column(ArrowType)
details = Column(JSONType) details = Column(JSONType)
location = Column(String) location = Column(String)
phone = Column(String) phone = Column(String)
@ -86,18 +93,27 @@ class Flat(BASE):
notes = Column(Text) notes = Column(Text)
notation = Column(SmallInteger, default=0) notation = Column(SmallInteger, default=0)
# Flatisfy data # Flatisfy found stations
# TODO: Should be in another table with relationships # TODO: What happens when one deletes a station?
flatisfy_stations = Column(JSONType) flatisfy_stations = relationship("PublicTransport",
flatisfy_postal_code = Column(String) secondary=stations_association_table)
# Flatisfy found postal code
# TODO: What happens when one deletes a postal code?
flatisfy_postal_code_id = Column(Integer, ForeignKey('postal_codes.id'))
flatisfy_postal_code = relationship("PostalCode")
# Computed time to
flatisfy_time_to = Column(JSONType) flatisfy_time_to = Column(JSONType)
flatisfy_constraint = Column(String) # Constraint relationship
# TODO: What happens when one deletes a constraint?
# TODO: A flat could match multiple constraints
flatisfy_constraint_id = Column(Integer, ForeignKey('constraints.id'))
flatisfy_constraint = relationship("Constraint")
# Status # Status
status = Column(Enum(FlatStatus), default=FlatStatus.new) status = Column(Enum(FlatStatus), default=FlatStatus.new)
# Date for visit # Date for visit
visit_date = Column(ArrowDate) visit_date = Column(ArrowType)
@validates('utilities') @validates('utilities')
def validate_utilities(self, _, utilities): def validate_utilities(self, _, utilities):