File size: 3,548 Bytes
b339b93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
-- Schema for Paper Trail API canonical database.
-- This file intentionally rebuilds the core tables and materialized views
-- required by the application and test suite. It can be rerun safely because
-- existing objects are dropped before creation.

DROP MATERIALIZED VIEW IF EXISTS canonical_politician_industry_summary;
DROP TABLE IF EXISTS votes CASCADE;
DROP TABLE IF EXISTS bill_topics CASCADE;
DROP TABLE IF EXISTS rollcalls CASCADE;
DROP TABLE IF EXISTS contributions CASCADE;
DROP TABLE IF EXISTS donors CASCADE;
DROP TABLE IF EXISTS politicians CASCADE;

CREATE TABLE politicians (
    politician_id TEXT PRIMARY KEY,
    first_name TEXT,
    last_name TEXT NOT NULL,
    full_name TEXT NOT NULL,
    party TEXT NOT NULL,
    state TEXT NOT NULL,
    seat TEXT NOT NULL,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    is_placeholder BOOLEAN NOT NULL DEFAULT FALSE,
    placeholder_type TEXT,
    icpsr_id INT,
    bioguide_id TEXT,
    nominate_dim1 NUMERIC,
    nominate_dim2 NUMERIC,
    first_elected_year INT,
    last_elected_year INT
);

CREATE TABLE donors (
    donor_id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    donor_type TEXT NOT NULL,
    igcat TEXT,
    employer TEXT,
    occupation TEXT,
    state TEXT,
    total_contributions_count INT NOT NULL DEFAULT 0,
    total_amount NUMERIC(14, 2) NOT NULL DEFAULT 0
);

CREATE TABLE contributions (
    transaction_id TEXT PRIMARY KEY,
    donor_id TEXT NOT NULL REFERENCES donors(donor_id) ON DELETE CASCADE,
    recipient_id TEXT NOT NULL REFERENCES politicians(politician_id) ON DELETE CASCADE,
    amount NUMERIC(14, 2) NOT NULL,
    transaction_date DATE NOT NULL,
    industry TEXT,
    election_cycle INT,
    raw_contributor_name TEXT,
    raw_employer TEXT
);

CREATE TABLE rollcalls (
    rollcall_id SERIAL PRIMARY KEY,
    congress INT NOT NULL,
    chamber TEXT NOT NULL,
    rollnumber INT NOT NULL,
    bill_number TEXT NOT NULL,
    bill_description TEXT NOT NULL,
    vote_date DATE NOT NULL,
    vote_result TEXT,
    has_topics BOOLEAN NOT NULL DEFAULT FALSE
);

CREATE TABLE bill_topics (
    topic_id SERIAL PRIMARY KEY,
    rollcall_id INT NOT NULL REFERENCES rollcalls(rollcall_id) ON DELETE CASCADE,
    topic_label TEXT NOT NULL,
    topic_source TEXT NOT NULL,
    topic_weight NUMERIC(6, 2),
    is_primary BOOLEAN NOT NULL DEFAULT FALSE
);

CREATE TABLE votes (
    vote_id SERIAL PRIMARY KEY,
    politician_id TEXT NOT NULL REFERENCES politicians(politician_id) ON DELETE CASCADE,
    rollcall_id INT NOT NULL REFERENCES rollcalls(rollcall_id) ON DELETE CASCADE,
    vote_value TEXT NOT NULL CHECK (vote_value IN ('Yea', 'Nay', 'Present', 'Not Voting'))
);

CREATE INDEX IF NOT EXISTS idx_votes_politician_id ON votes(politician_id);
CREATE INDEX IF NOT EXISTS idx_votes_rollcall_id ON votes(rollcall_id);
CREATE INDEX IF NOT EXISTS idx_bill_topics_rollcall_id ON bill_topics(rollcall_id);
CREATE INDEX IF NOT EXISTS idx_contributions_donor_id ON contributions(donor_id);
CREATE INDEX IF NOT EXISTS idx_contributions_recipient_id ON contributions(recipient_id);
CREATE INDEX IF NOT EXISTS idx_contributions_election_cycle ON contributions(election_cycle);

CREATE MATERIALIZED VIEW canonical_politician_industry_summary AS
SELECT
    p.politician_id,
    contributions.industry,
    COUNT(*) AS contribution_count,
    SUM(contributions.amount) AS total_amount,
    AVG(contributions.amount) AS avg_amount
FROM contributions
JOIN politicians p ON p.politician_id = contributions.recipient_id
GROUP BY p.politician_id, contributions.industry;