Превышено количество блокировок общего доступа к файлам // импорт Python для доступа к таблице.
Если кто-нибудь может помочь с этим, вы спасете жизнь. У меня есть сценарий на Python, который пытается автоматизировать ручной процесс, в котором пользователь импортирует .txt с 1 500 000 строк в таблицу доступа. При написании Python я использовал массовую вставку, которая в основном принимает фрейм данных, а затем разбивает его на .csv с некоторым размером строки, например 50 000, а затем вставляет в таблицу доступа из отдельных .csv.
Проблема в том, что это корпоративный компьютер, и я не могу увеличить значение MaxLocksPerFile по умолчанию, равное 9500. Я делаю 5000 строк. .csv файлы и фиксация каждых 10 пакетов. Итак, мы вставляем 5000 строк, пока не достигнет 50 000, а затем фиксируемся. Он делает около 350 000, прежде чем выдает ошибку «Превышено количество блокировок общего доступа к файлам».
Я перепробовал все возможные комбинации размера пакета и интервала фиксации. Я много раз пытался выполнить выполнение одного оператора sql, я пытался выполнить команду «execute», чтобы загрузить 1,5 миллиона строк, а затем зафиксировать их. Все провалилось.
Кто-нибудь делал подобное в Access? Кроме того, прежде чем вы скажете, что нужно использовать более надежную БД, я бы сделал это, если бы мог. Мой директор до сих пор использует Access, так что на данный момент я застрял на нем. Если бы я мог, я бы использовал сервер Sql.
Здесь код: функция для импорта данных
def bulk_insert_to_access(file_path, table_name, temp_file_path=None, chunk_size=5000, commit_interval=100):
"""
Inserts data from a dataframe to Access using an optimized bulk insert.
This method works by saving data to a temporary CSV file and then using an SQL SELECT INTO command.
"""
# Step 1: Read the .txt file and prepare the dataframe
df = pd.read_csv(file_path, delimiter="\t", encoding="utf-8")
# Adjust your data as needed (like column cleaning, etc.)
column_specs = get_column_specs(table_name)
df_adjusted = adjust_data_to_specs(df, column_specs)
if not temp_file_path:
temp_file_path = c for os.path.dirname(file_path)
# Break DF into chunks
chunks = [df_adjusted.iloc[i:i + chunk_size] for i in range(0, len(df_adjusted), chunk_size)]
# List to keep track of temporary files for cleanup later
chunk_file_paths = []
# Step 2: Perform the bulk insert via SQL SELECT INTO method
conn = pyodbc.connect(connect_str)
cursor = conn.cursor()
try:
for idx, chunk in enumerate(chunks):
# Save the chunk to a temporary CSV file
chunk_file_path = os.path.join(temp_file_path, f"temp_data_chunk_{idx}.csv")
chunk.to_csv(chunk_file_path, index=False, header=False) # Save to temporary file
chunk_file_paths.append(chunk_file_path) # Track file for later cleanup
# Perform the bulk insert for each chunk
sql = f"""
INSERT INTO [{table_name}]
SELECT * FROM [Text;FMT=TabDelimited;HDR=NO;DATABASE={os.path.dirname(chunk_file_path)}].[{os.path.basename(chunk_file_path)}]
"""
try:
# Execute SQL statement to insert data from chunked file
start_time = time.time()
cursor.execute(sql)
# Commit after every `commit_interval` chunks
if (idx + 1) % commit_interval == 0:
conn.commit()
time.sleep(1) # Add a small delay after commit to release locks
elapsed_time = time.time() - start_time
print(f"Bulk insert for chunk {idx} completed in {elapsed_time:.2f} seconds")
except pyodbc.Error as e:
print(f"Error during bulk insert for chunk {idx}: {e}")
conn.rollback() # Rollback only the current chunk
# Commit after the last chunk if not already committed
conn.commit()
except pyodbc.Error as e:
print(f"Error during the bulk insert process: {e}")
conn.rollback()
finally:
# Cleanup temporary files
for file_path in chunk_file_paths:
if os.path.exists(file_path):
try:
os.remove(file_path)
except OSError as e:
print(f"Error deleting temporary file {file_path}: {e}")
cursor.close()
conn.close()
Подробнее здесь: https://stackoverflow.com/questions/792 ... ulk-insert
Избегайте блокировки общего доступа к файлам в MS Access во время массовой вставки. ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение