42 lines
1.8 KiB
Python
42 lines
1.8 KiB
Python
"""Reproducible, benchmark-informed synthetic histories, never real player data.
|
|
|
|
See SAMPLE_DATA.md for public references, assumptions, and validation commands.
|
|
All writes belong to the caller's transaction. Existing game IDs are preserved.
|
|
"""
|
|
from collections import Counter, defaultdict
|
|
from datetime import datetime, timedelta, timezone
|
|
import math
|
|
from pathlib import Path
|
|
import random
|
|
|
|
from psycopg import sql
|
|
from psycopg.types.json import Jsonb
|
|
|
|
SAMPLE_KEYS = ('willow-v1', 'orbit-v1', 'dungeon-v1')
|
|
DAY = timedelta(days=1)
|
|
|
|
|
|
def copy_rows(conn, table, columns, records):
|
|
if not records:
|
|
return
|
|
query = sql.SQL('COPY {} ({}) FROM STDIN').format(
|
|
sql.Identifier(table), sql.SQL(',').join(map(sql.Identifier, columns)))
|
|
with conn.cursor().copy(query) as stream:
|
|
for row in records:
|
|
stream.write_row(tuple(Jsonb(v) if isinstance(v, (dict, list)) else v for v in row))
|
|
|
|
|
|
def reset_sample(conn):
|
|
"""Remove only the bundled samples; keep games and unrelated projects intact."""
|
|
gids = [r['id'] for r in conn.execute('SELECT id FROM games WHERE sample_key=ANY(%s)', (list(SAMPLE_KEYS),))]
|
|
for table in ('daily_health_reports', 'interaction_events', 'gamepass_ownership', 'product_sales', 'activity_runs', 'events',
|
|
'player_snapshots', 'sessions', 'game_metrics', 'players',
|
|
'gamepasses', 'products', 'activity_definitions', 'column_templates', 'player_fields'):
|
|
conn.execute(sql.SQL('DELETE FROM {} WHERE game_id=ANY(%s)').format(sql.Identifier(table)), (gids,))
|
|
|
|
|
|
def populate(conn,players_per_game=None):
|
|
"""Generate the current three-genre scenario fixtures; preserve shared COPY/reset helpers."""
|
|
from scenario_seed import populate as generate_scenarios
|
|
return generate_scenarios(conn,players_per_game)
|