Я пытаюсь использовать SQLSoup - расширение SQLAlchemy для обновления записей в базе данных SQL Server 2008.Я использую pyobdc для соединений.Есть ряд проблем, которые затрудняют поиск подходящего примера.
Я перепроецирую геометрическое поле в очень большой таблице (более 2 миллионов записей), поэтому многие стандартные способы обновления полей использовать нельзя.Мне нужно извлечь координаты из поля геометрии в текст, преобразовать их и передать обратно. Все это хорошо, и все отдельные части работают.
Однако я хочу выполнить инструкцию SQL Update для каждой строки, одновременно просматривая записи по очереди.Я предполагаю, что это блокирует набор записей или соединение используется - как будто я использую приведенный ниже код, который зависает после успешного обновления первой записи.
Любой совет о том, как создать новое соединение, повторно использовать существующее или выполнить это другим способом, приветствуется.
s = select([text("%s as fid" % id_field),
text("%s.STAsText() as wkt" % geom_field)],
from_obj=[feature_table])
rs = s.execute()
for row in rs:
new_wkt = ReprojectFeature(row.wkt)
update_value = "geometry :: STGeomFromText('%s',%s)" % (new_wkt, "3785")
update_sql = ("update %s set GEOM3785 = %s where %s = %i" %
(full_name, update_value, id_field, row.fid))
conn = db.connection()
conn.execute(update_sql)
conn.close() #or not - no effect..
Обновленный рабочий код теперь выглядит следующим образом.Он отлично работает на нескольких записях, но зависает на всей таблице, поэтому я думаю, что он читает слишком много данных.
db = SqlSoup(conn_string)
#create outer query
Session = sessionmaker(autoflush=False, bind=db.engine)
session = Session()
rs = session.execute(s)
for row in rs:
#create update sql...
session.execute(update_sql)
session.commit()
Теперь я получаю сообщения об ошибках соединения.
DBAPIError: (Ошибка) ('HY000', '[HY000] [Microsoft] [Драйвер ODBC SQL Server] Соединение установленозанят результатами для другого hstmt (0) (SQLExecDirectW) ')
Похоже, это может быть проблема с драйвером ODBC - http://sourceitsoftware.blogspot.com/2008/06/connection-is-busy-with-results-for.html
Дальнейшее обновление:
На сервере, использующем профилировщик, он показывает оператор выбора, после чего первый оператор обновления «запускается», но не завершается.Если я задаю оператор Select для возврата первых 10 строк, то он завершается и обновления запускаются.
SQL: Batch Starting Select...
SQL: Batch Starting Update...
Я думаю, что это проблема с pyodbc и драйверами SQL Server.Если я удаляю SQL Alchemy и выполняю тот же SQL с pyodbc, он также зависает.Даже если я создаю новый объект подключения для обновлений.
Я также попробовал драйвер SQL Server Native Client 10.0, который позволяет использовать MARS - множественных активных наборов записей , но это не имело никакого значения.В конце я прибег к «разбивке по страницам результатов» и обновлению этих пакетов с использованием pyodbc и SQL (см. Ниже), однако я подумал, что SQLAlchemy сможет сделать это для меня автоматически.