125 lines
3.7 KiB
Python
125 lines
3.7 KiB
Python
"""Bill model - legislation introduced in Congress."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date, datetime
|
|
from enum import StrEnum
|
|
from typing import TYPE_CHECKING
|
|
|
|
from sqlalchemy import DateTime, Enum, ForeignKey, Index, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from pipelines.orm.data_science_dev.base import DataScienceDevTableBase
|
|
|
|
if TYPE_CHECKING:
|
|
from pipelines.orm.data_science_dev.congress.legislator import LegislatorBillScore
|
|
from pipelines.orm.data_science_dev.congress.vote import Vote
|
|
|
|
|
|
class BillTopicPosition(StrEnum):
|
|
"""Whether a yes vote on a bill is for or against a topic."""
|
|
|
|
FOR = "for"
|
|
AGAINST = "against"
|
|
|
|
|
|
class Bill(DataScienceDevTableBase):
|
|
"""Legislation with congress number, type, titles, status, and sponsor."""
|
|
|
|
__tablename__ = "bill"
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
"congress", "bill_type", "number", name="uq_bill_congress_type_number"
|
|
),
|
|
Index("ix_bill_congress", "congress"),
|
|
)
|
|
|
|
congress: Mapped[int]
|
|
bill_type: Mapped[str]
|
|
number: Mapped[int]
|
|
|
|
title: Mapped[str | None]
|
|
title_short: Mapped[str | None]
|
|
official_title: Mapped[str | None]
|
|
|
|
status: Mapped[str | None]
|
|
status_at: Mapped[date | None]
|
|
|
|
sponsor_bioguide_id: Mapped[str | None]
|
|
|
|
subjects_top_term: Mapped[str | None]
|
|
score_processed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
|
|
votes: Mapped[list[Vote]] = relationship(
|
|
"Vote",
|
|
back_populates="bill",
|
|
)
|
|
bill_texts: Mapped[list[BillText]] = relationship(
|
|
"BillText",
|
|
back_populates="bill",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
topics: Mapped[list[BillTopic]] = relationship(
|
|
"BillTopic",
|
|
back_populates="bill",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
legislator_bill_scores: Mapped[list[LegislatorBillScore]] = relationship(
|
|
"LegislatorBillScore",
|
|
back_populates="bill",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
|
|
|
|
class BillText(DataScienceDevTableBase):
|
|
"""Stores different text versions of a bill (introduced, enrolled, etc.)."""
|
|
|
|
__tablename__ = "bill_text"
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
"bill_id", "version_code", name="uq_bill_text_bill_id_version_code"
|
|
),
|
|
)
|
|
|
|
bill_id: Mapped[int] = mapped_column(ForeignKey("main.bill.id", ondelete="CASCADE"))
|
|
version_code: Mapped[str]
|
|
version_name: Mapped[str | None]
|
|
text_content: Mapped[str | None]
|
|
summary: Mapped[str | None]
|
|
date: Mapped[date | None]
|
|
|
|
bill: Mapped[Bill] = relationship("Bill", back_populates="bill_texts")
|
|
|
|
|
|
class BillTopic(DataScienceDevTableBase):
|
|
"""One bill stance on one topic used to score roll-call votes."""
|
|
|
|
__tablename__ = "bill_topic"
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
"bill_id",
|
|
"topic",
|
|
"support_position",
|
|
name="uq_bill_topic_bill_id_topic_support_position",
|
|
),
|
|
Index("ix_bill_topic_topic", "topic"),
|
|
)
|
|
|
|
bill_id: Mapped[int] = mapped_column(ForeignKey("main.bill.id", ondelete="CASCADE"))
|
|
topic: Mapped[str]
|
|
support_position: Mapped[BillTopicPosition] = mapped_column(
|
|
Enum(
|
|
BillTopicPosition,
|
|
values_callable=lambda enum_cls: [member.value for member in enum_cls],
|
|
native_enum=False,
|
|
name="bill_topic_position",
|
|
)
|
|
)
|
|
|
|
bill: Mapped[Bill] = relationship("Bill", back_populates="topics")
|
|
legislator_bill_scores: Mapped[list[LegislatorBillScore]] = relationship(
|
|
"LegislatorBillScore",
|
|
back_populates="bill_topic",
|
|
cascade="all, delete-orphan",
|
|
)
|