Add ORM models for the pixel grids
- add Grid, Pixel, and AddressPixelAssociation ORM models - each Grid belongs to a City an is characterized by the side_length of all the square Pixels contained in it - Pixels aggregate Addresses => many-to-many relationship (that is modeled with SQLAlchemy's Association Pattern to implement a couple of constraints)
This commit is contained in:
parent
6cb4be80f6
commit
f996376b13
15 changed files with 665 additions and 36 deletions
56
src/urban_meal_delivery/db/addresses_pixels.py
Normal file
56
src/urban_meal_delivery/db/addresses_pixels.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
"""Model for the many-to-many relationship between `Address` and `Pixel` objects."""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from urban_meal_delivery.db import meta
|
||||
|
||||
|
||||
class AddressPixelAssociation(meta.Base):
|
||||
"""Association pattern between `Address` and `Pixel`.
|
||||
|
||||
This approach is needed here mainly because it implicitly
|
||||
updates the `_city_id` and `_grid_id` columns.
|
||||
|
||||
Further info:
|
||||
https://docs.sqlalchemy.org/en/stable/orm/basic_relationships.html#association-object # noqa:E501
|
||||
"""
|
||||
|
||||
__tablename__ = 'addresses_pixels'
|
||||
|
||||
# Columns
|
||||
_address_id = sa.Column('address_id', sa.Integer, primary_key=True)
|
||||
_city_id = sa.Column('city_id', sa.SmallInteger, nullable=False)
|
||||
_grid_id = sa.Column('grid_id', sa.SmallInteger, nullable=False)
|
||||
_pixel_id = sa.Column('pixel_id', sa.Integer, primary_key=True)
|
||||
|
||||
# Constraints
|
||||
__table_args__ = (
|
||||
# An `Address` can only be on a `Grid` ...
|
||||
sa.ForeignKeyConstraint(
|
||||
['address_id', 'city_id'],
|
||||
['addresses.id', 'addresses.city_id'],
|
||||
onupdate='RESTRICT',
|
||||
ondelete='RESTRICT',
|
||||
),
|
||||
# ... if their `.city` attributes match.
|
||||
sa.ForeignKeyConstraint(
|
||||
['grid_id', 'city_id'],
|
||||
['grids.id', 'grids.city_id'],
|
||||
onupdate='RESTRICT',
|
||||
ondelete='RESTRICT',
|
||||
),
|
||||
# Each `Address` can only be on a `Grid` once.
|
||||
sa.UniqueConstraint('address_id', 'grid_id'),
|
||||
# An association must reference an existing `Grid`-`Pixel` pair.
|
||||
sa.ForeignKeyConstraint(
|
||||
['pixel_id', 'grid_id'],
|
||||
['pixels.id', 'pixels.grid_id'],
|
||||
onupdate='RESTRICT',
|
||||
ondelete='RESTRICT',
|
||||
),
|
||||
)
|
||||
|
||||
# Relationships
|
||||
address = orm.relationship('Address', back_populates='pixels')
|
||||
pixel = orm.relationship('Pixel', back_populates='addresses')
|
||||
Loading…
Add table
Add a link
Reference in a new issue