urban-meal-delivery/src/urban_meal_delivery/db/addresses_pixels.py

56 lines
1.8 KiB
Python

"""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(sa.Integer, primary_key=True)
city_id = sa.Column(sa.SmallInteger, nullable=False)
grid_id = sa.Column(sa.SmallInteger, nullable=False)
pixel_id = sa.Column(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')