У меня есть работающее приложение MERN, которое анализирует файл Excel и вставляет его в MongoDB. Он использует обещания и массовую вставку. Однако ему необходимо читать большие файлы: когда он читает менее 200 000 строк, он завершается более 7 минут. Однако при содержании более 200 000 строк произойдет сбой при чтении файла (недостаточно памяти в куче), даже не вставив его в базу данных. Проверив загрузку, он задействовал 100% процессора и около 60% памяти.
Вот моя функция MERN, она возвращает текстовый файл с записями строк, которые не были успешно вставлены в БД:
Я попробовал Microsoft Pilot преобразовать функцию в скрипт Python. Каким-то образом он конвертировался, но работал около 45 минут с одним и тем же файлом, содержащим менее 200 000 строк. Однако ресурсы, которые он использует, очень малы: 10 % для ЦП и 40 % для памяти.
Вот скрипт Python с отредактированными изменениями
import os
import pandas as pd
from pymongo import MongoClient, UpdateOne
from concurrent.futures import ThreadPoolExecutor
from dotenv import load_dotenv
import sys
import time
def to_title_case(value):
if isinstance(value, str):
return value.title()
return value
def process_entries(entries, batch_size):
operations = []
for entry in entries:
existing_record = db.respondents.find_one({"IDNumber": entry['IDNumber']})
if existing_record:
fields_to_check = ['regionName', 'provinceName', 'municipalityName', 'municipalityId', 'barangayName']
parent_group = existing_record.get('parentGroup')
for field in fields_to_check:
if existing_record.get(field) != entry[field]:
parent_group = None
break
entry['parentGroup'] = parent_group
operations.append(UpdateOne(
{'IDNumber': entry['IDNumber']},
{'$set': entry},
upsert=True
))
if operations:
result = db.respondents.bulk_write(operations)
print(f"\rInserted {result.upserted_count} and updated {result.modified_count} documents") # Status update
return result.upserted_count + result.modified_count
return 0
def parse_excel_file(file_path, batch_size):
discrepancies = []
total_upserted_count = 0
# Check if the file exists
if not os.path.exists(file_path):
print(f"File not found: {file_path}")
return
df = pd.read_excel(file_path)
valid_entries = []
for index, row in df.iterrows():
sys.stdout.write(f"\rProcessing row {index + 2}") # Status update
sys.stdout.flush()
entry = {
'regionName': row.iloc[0],
'provinceName': row.iloc[1],
'municipalityName': row.iloc[2],
'barangayName': row.iloc[3],
'purokName': row.iloc[4].strip() if pd.notna(row.iloc[4]) else '',
'ID': row.iloc[5],
'firstname': to_title_case(row.iloc[6]),
...
}
location_match = db.locations.find_one({
'regionName': {'$regex': f'^{entry["regionName"]}$', '$options': 'i'},
'provinceName': {'$regex': f'^{entry["provinceName"]}$', '$options': 'i'},
'municipalityName': {'$regex': f'^{entry["municipalityName"]}$', '$options': 'i'},
'barangayName': {'$regex': f'^{entry["barangayName"]}$', '$options': 'i'}
})
if not location_match:
discrepancies.append({
'lineNumber': index + 2,
'IDNumber': entry['IDNumber'],
'regionName': entry['regionName'],
'provinceName': entry['provinceName'],
'municipalityName': entry['municipalityName'],
'barangayName': entry['barangayName']
})
else:
entry['regionName'] = location_match['regionName']
entry['provinceName'] = location_match['provinceName']
entry['municipalityName'] = location_match['municipalityName']
entry['municipalityId'] = location_match['municipalityId']
entry['barangayName'] = location_match['barangayName']
valid_entries.append(entry)
print(f"\nProcessed {len(valid_entries)} valid entries") # Status update
with ThreadPoolExecutor() as executor:
future_to_entry = {executor.submit(process_entries, valid_entries[i:i + batch_size], batch_size): i for i in range(0, len(valid_entries), batch_size)}
for future in future_to_entry:
try:
total_upserted_count += future.result()
except Exception as e:
print(f"Error processing batch {future_to_entry[future]}: {e}")
discrepancies.sort(key=lambda x: x['lineNumber'])
with open(os.path.join(BENEFICIARIES_DIRECTORY, f'{file_name}_discrepancy.txt'), 'w') as f:
for discrepancy in discrepancies:
f.write(f"Line {discrepancy['lineNumber']}, ID Number: {discrepancy['IDNumber']}, Region: {discrepancy['regionName']}, Province: {discrepancy['provinceName']}, Municipality: {discrepancy['municipalityName']}, Barangay: {discrepancy['barangayName']}\n")
print(f'Inserted {total_upserted_count} respondents. Check {file_name}_discrepancy.txt for rows with issues.')
def connect_to_mongo(env_file):
load_dotenv(env_file) # Load environment variables from the specified file
mongodb_uri = os.getenv('MONGODB_URI')
if not mongodb_uri:
print("MONGODB_URI not found in the .env file")
return False
try:
client = MongoClient(mongodb_uri)
db_name = mongodb_uri.split('/')[-1]
global db
db = client[db_name]
print(f"Connected to DB: {db_name}") # Debug print
# The 'server_info' method will throw an exception if the connection is not successful
client.server_info()
print("Successfully connected to MongoDB")
return True
except Exception as e:
print(f"Failed to connect to MongoDB: {e}")
return False
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Parse Excel file and upsert data to MongoDB')
parser.add_argument('env_file', type=str, help='Path to the .env file')
parser.add_argument('excel_file', type=str, help='Path to the Excel file to be parsed')
parser.add_argument('--batch-size', type=int, default=1000, help='Batch size for upsert operations')
args = parser.parse_args()
load_dotenv(args.env_file)
...
file_name = os.path.basename(args.excel_file)
file_path = os.path.join(BENEFICIARIES_DIRECTORY, file_name)
print(f"Full path of the Excel file: {file_path}") # Debug print
start_time = time.time() # Start the timer
if connect_to_mongo(args.env_file):
parse_excel_file(file_path, args.batch_size)
end_time = time.time() # End the timer
elapsed_time = end_time - start_time
hours, rem = divmod(elapsed_time, 3600)
minutes, seconds = divmod(rem, 60)
print(f"\nProcessing completed in {int(hours)} hours, {int(minutes)} minutes, and {int(seconds)} seconds")
print("Disconnected from MongoDB")
Можете ли вы просмотреть мою функцию Javascript и сценарий Python, чтобы узнать, можно ли их улучшить? Моя проблема с исходным Javascript — нехватка кучи памяти, а сценарий Python работает слишком медленно. Может ли Python использовать больше ресурсов, чтобы работать быстрее?
Дополнение:
Файл Excel уже находится на сервере. Поскольку он большой, его загрузка приведет к тайм-ауту соединения. Функция Javascript имеет исполняемую версию Javascript, которую использовал Co-Pilot и преобразовал ее в скрипт Python
У меня есть работающее приложение MERN, которое анализирует файл Excel и вставляет его в MongoDB. Он использует обещания и массовую вставку. Однако ему необходимо читать большие файлы: когда он читает менее 200 000 строк, он завершается более 7 минут. Однако при содержании более 200 000 строк произойдет сбой при чтении файла (недостаточно памяти в куче), даже не вставив его в базу данных. Проверив загрузку, он задействовал 100% процессора и около 60% памяти. Вот моя функция MERN, она возвращает текстовый файл с записями строк, которые не были успешно вставлены в БД: [code]... import fs from 'fs'; import { join } from 'path'; import path from 'path'; import ExcelJS from 'exceljs'; ... const parseExcelFile = async (req, res) => { const { fileName } = req.params; const filePath = path.join(directoryPath, fileName); const discrepancies = []; // holder for errors in parsing row let totalUpsertedCount = 0;
const upsertEntries = async (entries) => { for (let i = 0; i < entries.length; i += BATCH_SIZE) { const batch = entries.slice(i, i + BATCH_SIZE); const operations = await Promise.all(batch.map(async (entry) => { const existingRecord = await Respondent.findOne({ IDNumber: entry.IDNumber });
if (existingRecord) { const fieldsToCheck = ['regionName', 'provinceName', 'municipalityName', 'municipalityId', 'barangayName']; let parentGroup = existingRecord.parentGroup;
for (const field of fieldsToCheck) { if (existingRecord[field] !== entry[field]) { parentGroup = null; break; } }
res.status(200).send(discrepanciesContent); } catch (error) { res.status(500).send({ message: "Failed to parse Excel file", error: error.message }); } }; [/code] Я попробовал Microsoft Pilot преобразовать функцию в скрипт Python. Каким-то образом он конвертировался, но работал около 45 минут с одним и тем же файлом, содержащим менее 200 000 строк. Однако ресурсы, которые он использует, очень малы: 10 % для ЦП и 40 % для памяти. Вот скрипт Python с отредактированными изменениями [code]import os import pandas as pd from pymongo import MongoClient, UpdateOne from concurrent.futures import ThreadPoolExecutor from dotenv import load_dotenv import sys import time
def to_title_case(value): if isinstance(value, str): return value.title() return value
def process_entries(entries, batch_size): operations = [] for entry in entries: existing_record = db.respondents.find_one({"IDNumber": entry['IDNumber']}) if existing_record: fields_to_check = ['regionName', 'provinceName', 'municipalityName', 'municipalityId', 'barangayName'] parent_group = existing_record.get('parentGroup') for field in fields_to_check: if existing_record.get(field) != entry[field]: parent_group = None break entry['parentGroup'] = parent_group
if operations: result = db.respondents.bulk_write(operations) print(f"\rInserted {result.upserted_count} and updated {result.modified_count} documents") # Status update return result.upserted_count + result.modified_count return 0
print(f"\nProcessed {len(valid_entries)} valid entries") # Status update
with ThreadPoolExecutor() as executor: future_to_entry = {executor.submit(process_entries, valid_entries[i:i + batch_size], batch_size): i for i in range(0, len(valid_entries), batch_size)} for future in future_to_entry: try: total_upserted_count += future.result() except Exception as e: print(f"Error processing batch {future_to_entry[future]}: {e}")
discrepancies.sort(key=lambda x: x['lineNumber'])
with open(os.path.join(BENEFICIARIES_DIRECTORY, f'{file_name}_discrepancy.txt'), 'w') as f: for discrepancy in discrepancies: f.write(f"Line {discrepancy['lineNumber']}, ID Number: {discrepancy['IDNumber']}, Region: {discrepancy['regionName']}, Province: {discrepancy['provinceName']}, Municipality: {discrepancy['municipalityName']}, Barangay: {discrepancy['barangayName']}\n")
print(f'Inserted {total_upserted_count} respondents. Check {file_name}_discrepancy.txt for rows with issues.')
def connect_to_mongo(env_file): load_dotenv(env_file) # Load environment variables from the specified file
mongodb_uri = os.getenv('MONGODB_URI') if not mongodb_uri: print("MONGODB_URI not found in the .env file") return False
try: client = MongoClient(mongodb_uri) db_name = mongodb_uri.split('/')[-1] global db db = client[db_name] print(f"Connected to DB: {db_name}") # Debug print # The 'server_info' method will throw an exception if the connection is not successful client.server_info() print("Successfully connected to MongoDB") return True except Exception as e: print(f"Failed to connect to MongoDB: {e}") return False
if __name__ == "__main__": import argparse
parser = argparse.ArgumentParser(description='Parse Excel file and upsert data to MongoDB') parser.add_argument('env_file', type=str, help='Path to the .env file') parser.add_argument('excel_file', type=str, help='Path to the Excel file to be parsed') parser.add_argument('--batch-size', type=int, default=1000, help='Batch size for upsert operations') args = parser.parse_args()
load_dotenv(args.env_file) ... file_name = os.path.basename(args.excel_file) file_path = os.path.join(BENEFICIARIES_DIRECTORY, file_name) print(f"Full path of the Excel file: {file_path}") # Debug print start_time = time.time() # Start the timer
if connect_to_mongo(args.env_file): parse_excel_file(file_path, args.batch_size) end_time = time.time() # End the timer elapsed_time = end_time - start_time hours, rem = divmod(elapsed_time, 3600) minutes, seconds = divmod(rem, 60) print(f"\nProcessing completed in {int(hours)} hours, {int(minutes)} minutes, and {int(seconds)} seconds") print("Disconnected from MongoDB")
[/code] Можете ли вы просмотреть мою функцию Javascript и сценарий Python, чтобы узнать, можно ли их улучшить? Моя проблема с исходным Javascript — нехватка кучи памяти, а сценарий Python работает слишком медленно. Может ли Python использовать больше ресурсов, чтобы работать быстрее? Дополнение: Файл Excel уже находится на сервере. Поскольку он большой, его загрузка приведет к тайм-ауту соединения. Функция Javascript имеет исполняемую версию Javascript, которую использовал Co-Pilot и преобразовал ее в скрипт Python
У меня есть работающее приложение MERN, которое анализирует файл Excel и вставляет его в MongoDB. Он использует обещания и массовую вставку. Однако ему необходимо читать большие файлы: когда он читает менее 200 000 строк, он завершается более 7...
Я работаю над проектом, который требует не менее 500 КБ памяти. У меня есть SDK с этим кодом, определяющим стек и кучу, и он работает нормально. Stack_Size EQU 0x00004000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size...
Я работаю над проектом, который требует не менее 500 КБ памяти. У меня есть SDK с этим кодом, определяющим стек и кучу, и он работает нормально.Stack_Size EQU 0x00004000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size...
Я пытаюсь реализовать функцию рекурсивной мощности в C ++, но она не удается с большим N из -за переполнения стека. Вот код:
class Solution {
public:
double myPow(double x, int n) {
long long exp = n;
if (exp
Это хорошо работает для небольших...
Я разработал панель администратора ресторана с использованием стека MERN (MongoDB, Express.js, React, Node.js) и теперь хочу реализовать линейную регрессию для прогнозирования продаж или прогнозирования потока клиентов на основе исторических данных....