Если я правильно понимаю проблему, вам просто нужно указать имя для os.mkdir()
(не os.makedirs()
), что можно сделать с помощью того же метода, который вы используете для печати! Вот пример:
from lxml import html
import pathlib
import requests
from bs4 import BeautifulSoup as bs
import re
import sys
import os
import lxml.html
url = sys.argv[1]
page = requests.get(url)
tree = lxml.html.fromstring(page.content)
names = tree.xpath('//div[@class="course-title"]/text()')
names = filter(lambda n: n.strip(), names)
table = str.maketrans(dict.fromkeys('?:/'))
for index, name in enumerate(names):
print('{}MY - {}'.format(index, name.strip().translate(table)))
os.mkdir('{}'.format(name.strip().translate(table)))
Использовать SAVEPOINT
s, например.
BEGIN TRANSACTION
EXEC myLogSP
SAVE TRANSACTION savepointA
EXEC @err = myBusinessSPa
IF (@err <> 0) BEGIN
ROLLBACK TRANSACTION savepointA
COMMIT
RETURN -1
END
EXEC myLogSP
SAVE TRANSACTION savepointB
EXEC @err = myBusinessSPb
IF (@err <> 0) BEGIN
ROLLBACK TRANSACTION savepointB
COMMIT
RETURN -1
END
EXEC myLogSP
SAVE TRANSACTION savepointC
EXEC @err = myBusinessSPc
IF (@err <> 0) BEGIN
ROLLBACK TRANSACTION savepointC
COMMIT
RETURN -1
END
EXEC myLogSP
COMMIT TRANSACTION
Править
На основе информации, предоставленной до сих пор (и мое понимание его), кажется, что необходимо будет повторно спроектировать Вас регистрирующий SPS, или чтобы использовать переменные, или использовать файлы или позволить им работать 'за фактом' следующим образом:
BEGIN TRANSACTION
SAVE TRANSACTION savepointA
EXEC @err = myBusinessSPa
IF (@err <> 0) BEGIN
ROLLBACK TRANSACTION savepointA
EXEC myLogSPA -- the call to myBusinessSPa was attempted/failed
COMMIT
RETURN -1
END
SAVE TRANSACTION savepointB
EXEC @err = myBusinessSPb
IF (@err <> 0) BEGIN
ROLLBACK TRANSACTION savepointB
EXEC myLogSPA -- the call to myBusinessSPa originally succeeded
EXEC myLogSPB -- the call to myBusinessSPb was attempted/failed
COMMIT
RETURN -1
END
SAVE TRANSACTION savepointC
EXEC @err = myBusinessSPc
IF (@err <> 0) BEGIN
ROLLBACK TRANSACTION savepointC
EXEC myLogSPA -- the call to myBusinessSPa originally succeeded
EXEC myLogSPB -- the call to myBusinessSPb originally succeeded
EXEC myLogSPC -- the call to myBusinessSPc was attempted/failed
COMMIT
RETURN -1
END
EXEC myLogSPA -- the call to myBusinessSPa succeeded
EXEC myLogSPB -- the call to myBusinessSPb succeeded
EXEC myLogSPC -- the call to myBusinessSPc succeeded
COMMIT TRANSACTION
Необходимо в основном перейти за пределами текущего контекста. Существует несколько способов сделать это. Один (который я никогда не пробовал) должен назвать CLR, чтобы сделать вставку.
Возможно, лучший путь, хотя использует то, что табличные переменные не затронуты транзакцией. Например:
CREATE TABLE dbo.Test_Transactions
(
my_string VARCHAR(20) NOT NULL
)
GO
DECLARE
@tbl TABLE (my_string VARCHAR(20) NOT NULL)
BEGIN TRANSACTION
INSERT INTO dbo.Test_Transactions (my_string) VALUES ('test point one')
INSERT INTO @tbl (my_string) VALUES ('test point two')
INSERT INTO dbo.Test_Transactions (my_string) VALUES ('test point three')
ROLLBACK TRANSACTION
INSERT INTO dbo.Test_Transactions (my_string) select my_string from @tbl
SELECT * FROM dbo.Test_Transactions
SELECT * FROM @tbl
GO
Возможно, Вы могли поместить вставление/обновление в бизнес-таблицы в их собственной атомарной транзакции t1 и перенести каждую из этих транзакций в другой транзакции t2, который выполняет обновление таблицы журнала и t1 (бизнес-обновления таблицы) без любых откатов. Например:
BEGIN TRANSACTION t2
<insert to log>
<execute stored procedure p1>
END TRANSACTION t2
CREATE PROCEDURE p1
AS
BEGIN TRANSACTION t1
<insert to business tables>
<rollback t1 on error>
END TRANSACTION t1
Я полагаю, что, когда Вы откатываете t1 в хранимой процедуре, это оставит транзакцию вызова t2 незатронутой.
У нас была удача с помещением записей в журнале в табличные переменные и затем вставку в реальные таблицы после фиксации или отката.
Хорошо, если Вы не находитесь на SQL Server 2008, затем попробуйте этот метод. Это грязно и обходное решение, но это должно работать. #temp таблица и табличная переменная должны были бы быть настроены со структурой того, что возвращается SP.
create table #templog (fie1d1 int, field2 varchar(10))
declare @templog table (fie1d1 int, field2 varchar(10))
BEGIN TRANSACTION
insert into #templog
Exec my_proc
insert into @templog (fie1d1, field2)
select t.* from #templog t
left join @templog t2 on t.fie1d1 = t2.fie1d1 where t2.fie1d1 is null
insert into templog
values (1, 'test')
rollback tran
select * from #templog
select * from templog
select * from @templog
Разве простой способ не состоял бы в том, чтобы переместить вставку журнала вне транзакции?
У меня действительно нет ответа для Вас для блокировки таблицы, я думаю, что у Вас уже есть ответ, должна будет быть блокировка таблицы, потому что столбец идентификационных данных может откатывать.
Используйте ТОЧКИ СОХРАНЕНИЯ и УРОВНИ ИЗОЛЯЦИИ ТРАНЗАКЦИИ.
переместите оператор BEGIN TRANSACTION в после первой вставки.