56 lines
1.8 KiB
Python
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')
|