Metrics Backfill Plan: PostgreSQL to ClickHouse
Overview
Backfill metric data from PostgreSQL metric tables to ClickHouse entityMetricEvents_new table. This will allow us to have a unified source of truth for metrics in ClickHouse with version 3 indicating backfilled data.
Decisions Summary
| Decision |
Value |
| Timeframe |
AllTime only |
| Version |
3 (backfill identifier) |
| userId |
-1 (backfill marker) |
| Metric naming |
Use existing ClickHouse conventions |
| createdAt |
Fixed configurable date |
| Re-run behavior |
Delete existing backfill data before insert |
| Execution |
One table at a time via CLI argument |
Column Mapping: PostgreSQL → ClickHouse
Article
| PG Column |
CH metricType |
Status |
| likeCount |
Like |
existing |
| dislikeCount |
Dislike |
new |
| laughCount |
Laugh |
existing |
| cryCount |
Cry |
existing |
| heartCount |
Heart |
existing |
| commentCount |
commentCount |
existing |
| viewCount |
viewCount |
new |
| collectedCount |
collectedCount |
existing |
| tippedCount |
tippedCount |
existing |
| tippedAmountCount |
tippedAmount |
existing |
Bounty
| PG Column |
CH metricType |
Status |
| favoriteCount |
favoriteCount |
existing |
| trackCount |
trackCount |
existing |
| entryCount |
entryCount |
existing |
| benefactorCount |
benefactorCount |
existing |
| unitAmountCount |
unitAmount |
existing |
| commentCount |
commentCount |
existing |
BountyEntry
| PG Column |
CH metricType |
Status |
| likeCount |
Like |
existing |
| dislikeCount |
Dislike |
new |
| laughCount |
Laugh |
existing |
| cryCount |
Cry |
existing |
| heartCount |
Heart |
existing |
| unitAmountCount |
unitAmount |
existing |
| tippedCount |
tippedCount |
new |
| tippedAmountCount |
tippedAmount |
new |
Collection
| PG Column |
CH metricType |
Status |
| followerCount |
followerCount |
existing |
| itemCount |
itemCount |
existing |
| contributorCount |
contributorCount |
existing |
Image
| PG Column |
CH metricType |
Status |
| likeCount |
ReactionLike |
existing (using newer convention) |
| dislikeCount |
ReactionDislike |
new |
| laughCount |
ReactionLaugh |
existing |
| cryCount |
ReactionCry |
existing |
| heartCount |
ReactionHeart |
existing |
| commentCount |
Comment |
existing |
| collectedCount |
Collection |
existing |
| tippedCount |
tippedCount |
existing |
| tippedAmountCount |
tippedAmount |
existing |
| viewCount |
viewCount |
new |
Model
| PG Column |
CH metricType |
Status |
| downloadCount |
downloadCount |
existing |
| thumbsUpCount |
thumbsUpCount |
existing |
| thumbsDownCount |
thumbsDownCount |
existing |
| commentCount |
commentCount |
existing |
| collectedCount |
collectedCount |
existing |
| generationCount |
generationCount |
existing |
| imageCount |
imageCount |
existing |
| tippedCount |
tippedCount |
existing |
| tippedAmountCount |
tippedAmount |
existing |
| earnedAmount |
earnedAmount |
new |
| ratingCount |
ratingCount |
existing |
ModelVersion
| PG Column |
CH metricType |
Status |
| downloadCount |
downloadCount |
existing |
| thumbsUpCount |
thumbsUpCount |
existing |
| thumbsDownCount |
thumbsDownCount |
existing |
| commentCount |
commentCount |
new |
| collectedCount |
collectedCount |
new |
| generationCount |
generationCount |
existing |
| imageCount |
imageCount |
existing |
| tippedCount |
tippedCount |
new |
| tippedAmountCount |
tippedAmount |
new |
| earnedAmount |
earnedAmount |
new |
| ratingCount |
ratingCount |
existing |
Post
| PG Column |
CH metricType |
Status |
| likeCount |
Like |
existing |
| dislikeCount |
Dislike |
new |
| laughCount |
Laugh |
existing |
| cryCount |
Cry |
existing |
| heartCount |
Heart |
existing |
| commentCount |
commentCount |
existing |
| collectedCount |
collectedCount |
existing |
| tippedCount |
tippedCount |
existing |
| tippedAmountCount |
tippedAmount |
existing |
Tag
| PG Column |
CH metricType |
Status |
| modelCount |
modelCount |
new |
| imageCount |
imageCount |
new |
| postCount |
postCount |
new |
| articleCount |
articleCount |
new |
| hiddenCount |
hiddenCount |
existing |
| followerCount |
followerCount |
new |
User
| PG Column |
CH metricType |
Status |
| followerCount |
followerCount |
existing |
| followingCount |
followingCount |
existing |
| reactionCount |
reactionCount |
existing |
| hiddenCount |
hiddenCount |
existing |
| uploadCount |
uploadCount |
new |
| reviewCount |
reviewCount |
new |
ClickHouse Target Table
Implementation Plan
File Structure
Usage
Config Structure
Algorithm
Data Flow Example
Execution Order (Recommended)
Start with lowest-load tables first:
- BountyMetric - smallest, good for testing
- BountyEntryMetric
- CollectionMetric
- TagMetric
- ArticleMetric
- UserMetric
- PostMetric
- ModelMetric
- ModelVersionMetric
- ImageMetric - largest, run last
Next Steps
Confirm plan ✓
Confirm column mappings (pending review)
- Implement scripts in
scripts/metric-migration/
- Test with BountyMetric
- Validate data integrity
- Run remaining tables in order