SQLSoup (SQLAlchemy エクステンション) を使用して、SQL Server 2008 データベースのレコードを更新しようとしています。接続には pyobdc を使用しています。関連する例を見つけるのを難しくする問題がいくつかあります。
非常に大きなテーブル (200 万以上のレコード) のジオメトリ フィールドを再投影しているため、フィールドを更新する標準的な方法の多くは使用できません。ジオメトリ フィールドから座標をテキストに抽出し、変換して戻す必要があります。これですべて問題なく、個々の部分はすべて機能しています。
ただし、レコードを 1 つずつループしながら、各行で 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 Driver] Connection is busy with results for another hstmt (0) (SQLExecDirectW)')
これは ODBC ドライバーに問題があるようです - http://sourceitsoftware.blogspot.com/2008/06/connection-is-busy-with-results-for.html
さらなる更新:
プロファイラーを使用しているサーバーでは、選択ステートメントが表示され、最初の更新ステートメントは「開始」されていますが、どちらも完了していません。上位 10 行を返すように Select ステートメントを設定すると、ステートメントは完了し、更新が実行されます。
SQL: Batch Starting Select...
SQL: Batch Starting Update...
これはpyodbcと SQL Server ドライバーの問題だと思います。SQL Alchemy を削除して同じ SQL を pyodbc で実行すると、ハングします。更新用の新しい接続オブジェクトを作成しても。
また、MARS - Multiple Active Record Setsを許可する SQL Server Native Client 10.0 ドライバーも試しましたが、違いはありませんでした。最終的に、「結果をページング」し、pyodbc と SQL を使用してこれらのバッチを更新することにしました (以下を参照)。