Избегайте блокировки общего доступа к файлам в MS Access во время массовой вставки.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Избегайте блокировки общего доступа к файлам в MS Access во время массовой вставки.

Сообщение Anonymous »

Превышено количество блокировок общего доступа к файлам // импорт 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»