MCPcopy Create free account
hub / github.com/19-84/redd-archiver / insert_posts_batch

Method insert_posts_batch

core/postgres_database.py:765–962  ·  view source on GitHub ↗

Insert multiple posts in optimized batches using PostgreSQL COPY protocol. PostgreSQL COPY is 5-10x faster than INSERT statements for bulk loading. Target: 15,000+ posts/second vs SQLite's ~3,000/second. Args: posts: List of post dictionaries with Reddit JSON st

(
        self,
        posts: list[dict[str, Any]],
        progress_callback: Callable[[int, int], None] | None = None,
        auto_tune_batch_size: bool = True,
        initial_batch_size: int = 1000,
    )

Source from the content-addressed store, hash-verified

763
764 @retry_with_exponential_backoff(max_retries=5, initial_delay=2.0, max_delay=60.0)
765 def insert_posts_batch(
766 self,
767 posts: list[dict[str, Any]],
768 progress_callback: Callable[[int, int], None] | None = None,
769 auto_tune_batch_size: bool = True,
770 initial_batch_size: int = 1000,
771 ) -> tuple[int, int, set[str]]:
772 """Insert multiple posts in optimized batches using PostgreSQL COPY protocol.
773
774 PostgreSQL COPY is 5-10x faster than INSERT statements for bulk loading.
775 Target: 15,000+ posts/second vs SQLite's ~3,000/second.
776
777 Args:
778 posts: List of post dictionaries with Reddit JSON structure
779 progress_callback: Optional callback function(processed, total) for progress updates
780 auto_tune_batch_size: Whether to auto-tune batch size based on performance
781 initial_batch_size: Starting batch size (larger than SQLite due to better concurrency)
782
783 Returns:
784 Tuple of (successful_inserts, failed_inserts, failed_post_ids)
785 """
786 if not posts:
787 return 0, 0, set()
788
789 successful = 0
790 failed = 0
791 skipped = 0 # Track posts without valid IDs
792 failed_post_ids: set[str] = set() # Track which specific posts failed
793 total_posts = len(posts)
794 current_batch_size = initial_batch_size
795
796 start_time = time.time()
797
798 try:
799 with self.pool.get_connection() as conn:
800 # Disable synchronous_commit for bulk insert performance (10-20% faster)
801 # Transaction safety is maintained - rollback still works correctly
802 with conn.cursor() as cur:
803 cur.execute("SET LOCAL synchronous_commit = OFF")
804
805 for batch_start in range(0, total_posts, current_batch_size):
806 batch = posts[batch_start : batch_start + current_batch_size]
807 batch_size = len(batch)
808
809 batch_start_time = time.time()
810
811 try:
812 # Use PostgreSQL COPY protocol for true streaming (no buffering)
813 # This eliminates 350MB buffer overhead per batch
814 copy_buffer = StringIO()
815 records_prepared = 0
816
817 for post in batch:
818 # Validate post has a valid ID before attempting insertion
819 post_id = post.get("id")
820 if not post_id or (isinstance(post_id, str) and not post_id.strip()):
821 skipped += 1
822 continue

Callers 15

process_import_onlyFunction · 0.95
mainFunction · 0.95
seeded_db_moduleFunction · 0.95
_flush_batch_to_databaseFunction · 0.80
thumb_dbFunction · 0.80
update_dbFunction · 0.80
indexed_dbFunction · 0.80
test_no_flair_is_noopMethod · 0.80
flair_dbMethod · 0.80

Calls 11

_sanitize_recursiveMethod · 0.95
_escape_copy_textMethod · 0.95
_sanitize_valueMethod · 0.95
print_errorFunction · 0.90
print_successFunction · 0.90
print_warningFunction · 0.90
progress_callbackFunction · 0.85
get_connectionMethod · 0.80
executeMethod · 0.80
commitMethod · 0.80
rollbackMethod · 0.80

Tested by 15

seeded_db_moduleFunction · 0.76
thumb_dbFunction · 0.64
update_dbFunction · 0.64
indexed_dbFunction · 0.64
test_no_flair_is_noopMethod · 0.64
flair_dbMethod · 0.64
clean_databaseFunction · 0.64