Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions gittensor/validator/storage/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
import bittensor as bt

try:
import psycopg2
import psycopg

POSTGRES_AVAILABLE = True
except ImportError:
POSTGRES_AVAILABLE = False
bt.logging.warning('psycopg2 not installed. Database storage features will be disabled.')
bt.logging.warning('psycopg not installed. Database storage features will be disabled.')


def create_database_connection() -> Optional[Any]:
Expand All @@ -24,7 +24,7 @@ def create_database_connection() -> Optional[Any]:
Database connection if successful, None otherwise
"""
if not POSTGRES_AVAILABLE:
bt.logging.error('Cannot create database connection: psycopg2 not installed')
bt.logging.error('Cannot create database connection: psycopg not installed')
return None

try:
Expand All @@ -33,15 +33,17 @@ def create_database_connection() -> Optional[Any]:
'port': int(os.getenv('DB_PORT', 5432)),
'user': os.getenv('DB_USER', 'postgres'),
'password': os.getenv('DB_PASSWORD', ''),
'database': os.getenv('DB_NAME', 'gittensor_validator'),
'dbname': os.getenv('DB_NAME', 'gittensor_validator'),
}

connection = psycopg2.connect(**db_config)
connection = psycopg.connect(**db_config)
connection.autocommit = False
# Always prepare statements; bulk insert paths benefit immediately
connection.prepare_threshold = 0
bt.logging.success('Successfully connected to PostgreSQL database for validation result storage')
return connection

except psycopg2.Error as e:
except psycopg.Error as e:
bt.logging.error(f'Failed to connect to database: {e}')
return None
except Exception as e:
Expand Down
33 changes: 29 additions & 4 deletions gittensor/validator/storage/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@
additions, deletions, commits, total_nodes_scored,
merged_by_login, description, last_edited_at,
code_density, token_score, structural_count, structural_score, leaf_count, leaf_score
) VALUES %s
) VALUES (
%s, %s, %s, %s, %s, %s, %s,
%s, %s, %s,
%s, %s, %s,
%s, %s, %s, %s,
%s, %s, %s, %s,
%s, %s,
%s, %s, %s, %s,
%s, %s, %s,
%s, %s, %s, %s, %s, %s
)
ON CONFLICT (number, repository_full_name)
DO UPDATE SET
uid = EXCLUDED.uid,
Expand Down Expand Up @@ -100,7 +110,15 @@
discovery_review_quality_multiplier, discovery_repo_weight_multiplier,
discovery_time_decay_multiplier, discovery_credibility_multiplier,
discovery_open_issue_spam_multiplier
) VALUES %s
) VALUES (
%s, %s, %s, %s, %s, %s,
%s, %s, %s,
%s, %s, %s,
%s, %s,
%s, %s,
%s, %s,
%s
)
ON CONFLICT (number, pr_number, repository_full_name)
DO UPDATE SET
title = EXCLUDED.title,
Expand All @@ -124,7 +142,7 @@
BULK_UPSERT_FILE_CHANGES = """
INSERT INTO file_changes (
pr_number, repository_full_name, filename, changes, additions, deletions, status, patch, file_extension
) VALUES %s
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (pr_number, repository_full_name, filename)
DO UPDATE SET
changes = EXCLUDED.changes,
Expand All @@ -144,7 +162,14 @@
total_token_score, total_structural_count, total_structural_score, total_leaf_count, total_leaf_score,
issue_discovery_score, issue_token_score, issue_credibility, is_issue_eligible,
total_solved_issues, total_valid_solved_issues, total_closed_issues, total_open_issues
) VALUES %s
) VALUES (
%s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
%s, %s, %s,
%s, %s, %s, %s, %s,
%s, %s, %s, %s,
%s, %s, %s, %s
)
ON CONFLICT (uid, hotkey, github_id)
DO UPDATE SET
failed_reason = EXCLUDED.failed_reason,
Expand Down
34 changes: 4 additions & 30 deletions gittensor/validator/storage/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,7 @@ def store_pull_requests_bulk(self, pull_requests: List[PullRequest], commit: boo

try:
with self.get_cursor() as cursor:
from psycopg2.extras import execute_values

execute_values(
cursor,
BULK_UPSERT_PULL_REQUESTS.replace('VALUES %s', 'VALUES %s'),
values,
template=None,
page_size=100,
)
cursor.executemany(BULK_UPSERT_PULL_REQUESTS, values)
if commit:
self.db.commit()
return len(values)
Expand Down Expand Up @@ -268,15 +260,7 @@ def store_issues_bulk(self, issues: List[Issue], commit: bool = True) -> int:

try:
with self.get_cursor() as cursor:
from psycopg2.extras import execute_values

execute_values(
cursor,
BULK_UPSERT_ISSUES.replace('VALUES %s', 'VALUES %s'),
values,
template=None,
page_size=100,
)
cursor.executemany(BULK_UPSERT_ISSUES, values)
if commit:
self.db.commit()
return len(values)
Expand Down Expand Up @@ -319,15 +303,7 @@ def store_file_changes_bulk(self, file_changes: List[FileChange], commit: bool =

try:
with self.get_cursor() as cursor:
from psycopg2.extras import execute_values

execute_values(
cursor,
BULK_UPSERT_FILE_CHANGES.replace('VALUES %s', 'VALUES %s'),
values,
template=None,
page_size=100,
)
cursor.executemany(BULK_UPSERT_FILE_CHANGES, values)
if commit:
self.db.commit()
return len(values)
Expand Down Expand Up @@ -384,9 +360,7 @@ def set_miner_evaluation(self, evaluation: MinerEvaluation, commit: bool = True)

try:
with self.get_cursor() as cursor:
from psycopg2.extras import execute_values

execute_values(cursor, BULK_UPSERT_MINER_EVALUATION, eval_values)
cursor.executemany(BULK_UPSERT_MINER_EVALUATION, eval_values)
if commit:
self.db.commit()
return True
Expand Down
42 changes: 22 additions & 20 deletions gittensor/validator/utils/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ def store_evaluation(self, miner_eval: MinerEvaluation) -> StorageResult:

miner = Miner(miner_eval.uid, miner_eval.hotkey, miner_eval.github_id or '')

result.stored_counts['miners'] = self.repo.set_miner(miner, commit=False)

from gittensor.validator.oss_contributions.mirror.adapters import (
mirror_scored_pr_to_legacy_pull_request,
)
Expand All @@ -62,24 +60,28 @@ def _adapt_mirror(scored_list):
for s in scored_list
]

result.stored_counts['merged_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.merged_pull_requests + _adapt_mirror(miner_eval.mirror_merged_prs), commit=False
)
result.stored_counts['open_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.open_pull_requests + _adapt_mirror(miner_eval.mirror_open_prs), commit=False
)
result.stored_counts['closed_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.closed_pull_requests + _adapt_mirror(miner_eval.mirror_closed_prs), commit=False
)
result.stored_counts['stale_closed_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.stale_closed_pull_requests, commit=False
)
result.stored_counts['issues'] = self.repo.store_issues_bulk(miner_eval.get_all_issues(), commit=False)
result.stored_counts['file_changes'] = self.repo.store_file_changes_bulk(
miner_eval.get_all_file_changes(), commit=False
)
self.repo.cleanup_stale_miner_data(miner_eval, commit=False)
result.stored_counts['evaluations'] = 1 if self.repo.set_miner_evaluation(miner_eval, commit=False) else 0
with self.db_connection.pipeline():
result.stored_counts['miners'] = self.repo.set_miner(miner, commit=False)
result.stored_counts['merged_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.merged_pull_requests + _adapt_mirror(miner_eval.mirror_merged_prs), commit=False
)
result.stored_counts['open_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.open_pull_requests + _adapt_mirror(miner_eval.mirror_open_prs), commit=False
)
result.stored_counts['closed_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.closed_pull_requests + _adapt_mirror(miner_eval.mirror_closed_prs), commit=False
)
result.stored_counts['stale_closed_pull_requests'] = self.repo.store_pull_requests_bulk(
miner_eval.stale_closed_pull_requests, commit=False
)
result.stored_counts['issues'] = self.repo.store_issues_bulk(miner_eval.get_all_issues(), commit=False)
result.stored_counts['file_changes'] = self.repo.store_file_changes_bulk(
miner_eval.get_all_file_changes(), commit=False
)
self.repo.cleanup_stale_miner_data(miner_eval, commit=False)
result.stored_counts['evaluations'] = (
1 if self.repo.set_miner_evaluation(miner_eval, commit=False) else 0
)

self.db_connection.commit()
self.db_connection.autocommit = True
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies = [
"bittensor-wallet==4.0.0",
"click",
"levenshtein==0.27.3",
"psycopg2-binary==2.9.10",
"psycopg[binary]==3.3.3",
"python-dotenv==1.2.1",
"pytz==2025.2",
"rich",
Expand Down
Loading
Loading