Python 3.3.2 と pyodbc を使用して、プロジェクトのデータ同期スクリプトを開発しています。必要なデータは SQL Server 2008 インスタンスからのものですが、これまでのところ、クエリを正常に作成できていません。
pyodbc を使用してデータベース サーバーへの接続を確立できます。
cnxn = pyodbc.connect('DSN=<DSN>; UID=<uid>; PWD=<pwd>')
cursor = cnxn.cursor()
freetds および iodbc のログは、データベース サーバーへの接続が成功したことを示しています (ログには以下が含まれます)。ただし、クエリを実行しようとすると:
cursor.execute('select * from <TABLE>')
次のエラーが表示されます。
pyodbc.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Incorrect syntax near '�'. (102) (SQLExecDirectW)")
iodbc および FreeTDS ログは、「??????????????????????????????」を示しています。クエリとして渡されます。これは、ユニコード/エンコーディングの問題のように見えます。同じ pyodbc コードは、同じバージョンの iODBC と FreeTDS を使用する python 2.7 で動作するため、この問題は python 3.3.2 と pyodbc の間の相互作用に関係していると思います。
私はこのバグレポートを見つけましたが、まだ何らかの修正や回避策を見つけていません。どんな助けでも大歓迎です。私はこの 2 日間、これを理解しようとしてきましたが、あまり運がありませんでした。
参考になる情報が含まれていない場合はお知らせください。できる限りの情報を提供します。SQL Server ログにアクセスできません。
環境:
Mac OSX 10.8.5
Python 3.3.2
pyodbc 3.0.7
iODBC 3.52.6 (Mac で pyodbc に unixodbc を使用するよう説得する方法がわかりません)
FreeTDS 0.91
iODBC ログ:
[000000.000070]
python 7FFF7876C180 ENTER SQLAllocHandle
SQLSMALLINT 1 (SQL_HANDLE_ENV)
SQLHANDLE 0x0 (SQL_NULL_HANDLE)
SQLHANDLE * 0x1007b5970
[000000.000091]
python 7FFF7876C180 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 1 (SQL_HANDLE_ENV)
SQLHANDLE 0x0 (SQL_NULL_HANDLE)
SQLHANDLE * 0x1007b5970 (0x10049e350)
[000000.000110]
python 7FFF7876C180 ENTER SQLSetEnvAttr
SQLHENV 0x10049e350
SQLINTEGER 200 (SQL_ATTR_ODBC_VERSION)
SQLPOINTER 0x3
SQLINTEGER * 4
[000000.000508]
python 7FFF7876C180 EXIT SQLSetEnvAttr with return code 0 (SQL_SUCCESS)
SQLHENV 0x10049e350
SQLINTEGER 200 (SQL_ATTR_ODBC_VERSION)
SQLPOINTER 0x3
SQLINTEGER * 4
[000000.000527]
python 7FFF7876C180 ENTER SQLAllocHandle
SQLSMALLINT 2 (SQL_HANDLE_DBC)
SQLHANDLE 0x10049e350
SQLHANDLE * 0x7fff5fbff080
[000000.000545]
python 7FFF7876C180 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 2 (SQL_HANDLE_DBC)
SQLHANDLE 0x10049e350
SQLHANDLE * 0x7fff5fbff080 (0x1004c3bf0)
[000000.000569]
python 7FFF7876C180 ENTER SQLDriverConnectW
SQLHDBC 0x1004c3bf0
SQLPOINTER 0x0
SQLWCHAR * 0x1004c3cf0
| ??????????????????????????????????? |
SQLSMALLINT 39
SQLWCHAR * 0x0
SQLSMALLINT 0
SQLSMALLINT * 0x0
SQLUSMALLINT 0 (SQL_DRIVER_NOPROMPT)
[000000.000709]
python 7FFF7876C180 EXIT SQLDriverConnectW with return code -1 (SQL_ERROR)
SQLHDBC 0x1004c3bf0
SQLPOINTER 0x0
SQLWCHAR * 0x1004c3cf0
SQLSMALLINT 39
SQLWCHAR * 0x0
SQLSMALLINT 0
SQLSMALLINT * 0x0
SQLUSMALLINT 0 (SQL_DRIVER_NOPROMPT)
[000000.000740]
python 7FFF7876C180 ENTER SQLDriverConnect
SQLHDBC 0x1004c3bf0
SQLPOINTER 0x0
SQLCHAR * 0x7fff5fbff0a0
| DSN=<dsn>;UID=<uid>t;PWD=<pwd> |
SQLSMALLINT -3 (SQL_NTS)
SQLCHAR * 0x0
SQLSMALLINT 0
SQLSMALLINT * 0x0
SQLUSMALLINT 0 (SQL_DRIVER_NOPROMPT)
[000000.071429]
python 7FFF7876C180 EXIT SQLDriverConnect with return code 0 (SQL_SUCCESS)
SQLHDBC 0x1004c3bf0
SQLPOINTER 0x0
SQLCHAR * 0x7fff5fbff0a0
SQLSMALLINT -3 (SQL_NTS)
SQLCHAR * 0x0
SQLSMALLINT 0
SQLSMALLINT * 0x0
SQLUSMALLINT 0 (SQL_DRIVER_NOPROMPT)
[000000.071482]
python 7FFF7876C180 ENTER SQLSetConnectAttr
SQLHDBC 0x1004c3bf0
SQLINTEGER 102 (SQL_ATTR_AUTOCOMMIT)
SQLPOINTER 0x0
SQLINTEGER * 4294967291 (SQL_IS_UINTEGER)
[000000.089380]
python 7FFF7876C180 EXIT SQLSetConnectAttr with return code 0 (SQL_SUCCESS)
SQLHDBC 0x1004c3bf0
SQLINTEGER 102 (SQL_ATTR_AUTOCOMMIT)
SQLPOINTER 0x0
SQLINTEGER * 4294967291 (SQL_IS_UINTEGER)
[000000.089468]
python 7FFF7876C180 ENTER SQLGetInfo
SQLHDBC 0x1004c3bf0
SQLUSMALLINT 77 (SQL_DRIVER_ODBC_VER)
SQLPOINTER 0x7fff5fbff000
SQLSMALLINT 20
SQLSMALLINT * 0x7fff5fbfeffe
[000000.089502]
python 7FFF7876C180 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)
SQLHDBC 0x1004c3bf0
SQLUSMALLINT 77 (SQL_DRIVER_ODBC_VER)
SQLPOINTER 0x7fff5fbff000
| 03.50 |
SQLSMALLINT 20
SQLSMALLINT * 0x7fff5fbfeffe (5)
[000000.089529]
python 7FFF7876C180 ENTER SQLGetInfo
SQLHDBC 0x1004c3bf0
SQLUSMALLINT 10002 (SQL_DESCRIBE_PARAMETER)
SQLPOINTER 0x7fff5fbfeffc
SQLSMALLINT 2
SQLSMALLINT * 0x7fff5fbfeffe
[000000.089550]
python 7FFF7876C180 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)
SQLHDBC 0x1004c3bf0
SQLUSMALLINT 10002 (SQL_DESCRIBE_PARAMETER)
SQLPOINTER 0x7fff5fbfeffc
| N |
SQLSMALLINT 2
SQLSMALLINT * 0x7fff5fbfeffe (1)
[000000.089593]
python 7FFF7876C180 ENTER SQLGetInfo
SQLHDBC 0x1004c3bf0
SQLUSMALLINT 111 (SQL_NEED_LONG_DATA_LEN)
SQLPOINTER 0x7fff5fbfeffc
SQLSMALLINT 2
SQLSMALLINT * 0x7fff5fbfeffe
[000000.089615]
python 7FFF7876C180 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)
SQLHDBC 0x1004c3bf0
SQLUSMALLINT 111 (SQL_NEED_LONG_DATA_LEN)
SQLPOINTER 0x7fff5fbfeffc
| Y |
SQLSMALLINT 2
SQLSMALLINT * 0x7fff5fbfeffe (1)
[000000.089638]
python 7FFF7876C180 ENTER SQLAllocHandle
SQLSMALLINT 3 (SQL_HANDLE_STMT)
SQLHANDLE 0x1004c3bf0
SQLHANDLE * 0x7fff5fbfeff0
[000000.089669]
python 7FFF7876C180 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 (SQL_HANDLE_STMT)
SQLHANDLE 0x1004c3bf0
SQLHANDLE * 0x7fff5fbfeff0 (0x1004cabb0)
[000000.089686]
python 7FFF7876C180 ENTER SQLGetTypeInfo
SQLHSTMT 0x1004cabb0
SQLSMALLINT 93 (SQL_TYPE_TIMESTAMP)
[000000.111645]
python 7FFF7876C180 EXIT SQLGetTypeInfo with return code 0 (SQL_SUCCESS)
SQLHSTMT 0x1004cabb0
SQLSMALLINT 93 (SQL_TYPE_TIMESTAMP)
[000000.111684]
python 7FFF7876C180 ENTER SQLFetch
SQLHSTMT 0x1004cabb0
[000000.111711]
python 7FFF7876C180 EXIT SQLFetch with return code 0 (SQL_SUCCESS)
SQLHSTMT 0x1004cabb0
[000000.111724]
python 7FFF7876C180 ENTER SQLGetData
SQLHSTMT 0x1004cabb0
SQLUSMALLINT 3
SQLSMALLINT 4 (SQL_C_LONG)
SQLPOINTER 0x7fff5fbfefec
SQLLEN 4
SQLLEN * 0x0
[000000.111759]
python 7FFF7876C180 EXIT SQLGetData with return code 0 (SQL_SUCCESS)
SQLHSTMT 0x1004cabb0
SQLUSMALLINT 3
SQLSMALLINT 4 (SQL_C_LONG)
SQLPOINTER 0x7fff5fbfefec
| 21580870632603671 |
SQLLEN 4
SQLLEN * 0x0
[000000.111788]
python 7FFF7876C180 ENTER SQLGetTypeInfo
SQLHSTMT 0x1004cabb0
SQLSMALLINT 12 (SQL_VARCHAR)
[000000.111801]
python 7FFF7876C180 EXIT SQLGetTypeInfo with return code -1 (SQL_ERROR)
SQLHSTMT 0x1004cabb0
SQLSMALLINT 12 (SQL_VARCHAR)
[000000.111815]
python 7FFF7876C180 ENTER SQLGetTypeInfo
SQLHSTMT 0x1004cabb0
SQLSMALLINT -9 (SQL_WVARCHAR)
[000000.111828]
python 7FFF7876C180 EXIT SQLGetTypeInfo with return code -1 (SQL_ERROR)
SQLHSTMT 0x1004cabb0
SQLSMALLINT -9 (SQL_WVARCHAR)
[000000.111842]
python 7FFF7876C180 ENTER SQLGetTypeInfo
SQLHSTMT 0x1004cabb0
SQLSMALLINT -2 (SQL_BINARY)
[000000.111854]
python 7FFF7876C180 EXIT SQLGetTypeInfo with return code -1 (SQL_ERROR)
SQLHSTMT 0x1004cabb0
SQLSMALLINT -2 (SQL_BINARY)
[000000.111869]
python 7FFF7876C180 ENTER SQLFreeStmt
SQLHSTMT 0x1004cabb0
SQLUSMALLINT 0 (SQL_CLOSE)
[000000.132529]
python 7FFF7876C180 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)
SQLHSTMT 0x1004cabb0
SQLUSMALLINT 0 (SQL_CLOSE)
[000000.132590]
python 7FFF7876C180 ENTER SQLAllocHandle
SQLSMALLINT 3 (SQL_HANDLE_STMT)
SQLHANDLE 0x1004c3bf0
SQLHANDLE * 0x101373ee8
[000000.132629]
python 7FFF7876C180 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 (SQL_HANDLE_STMT)
SQLHANDLE 0x1004c3bf0
SQLHANDLE * 0x101373ee8 (0x10045c0b0)
[000123.339614]
python 7FFF7876C180 ENTER SQLFreeStmt
SQLHSTMT 0x10045c0b0
SQLUSMALLINT 0 (SQL_CLOSE)
[000123.339667]
python 7FFF7876C180 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)
SQLHSTMT 0x10045c0b0
SQLUSMALLINT 0 (SQL_CLOSE)
[000123.339718]
python 7FFF7876C180 ENTER SQLExecDirectW
SQLHSTMT 0x10045c0b0
SQLWCHAR * 0x10047a540
| ?????????????????????????????? |
SQLINTEGER -3 (SQL_NTS)
[000123.360756]
python 7FFF7876C180 EXIT SQLExecDirectW with return code -1 (SQL_ERROR)
SQLHSTMT 0x10045c0b0
SQLWCHAR * 0x10047a540
SQLINTEGER -3 (SQL_NTS)
[000123.361764]
python 7FFF7876C180 ENTER SQLGetDiagRec
SQLSMALLINT 3 (SQL_HANDLE_STMT)
SQLHSTMT 0x10045c0b0
SQLSMALLINT 1
SQLCHAR * 0x7fff5fbfeebc
SQLINTEGER * 0x7fff5fbfeec4
SQLCHAR * 0x7fff5fbfeed0
SQLSMALLINT 1023
SQLSMALLINT * 0x7fff5fbfeec2
[000123.361849]
python 7FFF7876C180 EXIT SQLGetDiagRec with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 (SQL_HANDLE_STMT)
SQLHSTMT 0x10045c0b0
SQLSMALLINT 1
SQLCHAR * 0x7fff5fbfeebc
| 42000 |
SQLINTEGER * 0x7fff5fbfeec4 (102)
SQLCHAR * 0x7fff5fbfeed0
| [FreeTDS][SQL Server]Incorrect syntax ne |
| ar '�'. |
SQLSMALLINT 1023
SQLSMALLINT * 0x7fff5fbfeec2 (49)
FreeTDS ログ:
token.c:2355:tds_process_end() state set to TDS_IDLE
util.c:156:Changed query state from READING to IDLE
token.c:2370: rows_affected = 0
odbc.c:1454:SQLAllocHandle(3, 0x1004caad0, 0x10045c1c8)
odbc.c:1615:_SQLAllocStmt(0x1004caad0, 0x10045c1c8)
odbc.c:4388:SQLGetStmtAttr(0x1004cb550, 10010, 0x1004ab428, 0, 0x0)
odbc.c:4388:SQLGetStmtAttr(0x1004cb550, 10011, 0x1004ca118, 0, 0x0)
odbc.c:4388:SQLGetStmtAttr(0x1004cb550, 10012, 0x1004ca158, 0, 0x0)
odbc.c:4388:SQLGetStmtAttr(0x1004cb550, 10013, 0x1004cb6b8, 0, 0x0)
odbc.c:4154:SQLFreeStmt(0x1004cb550, 0)
odbc.c:4075:_SQLFreeStmt(0x1004cb550, 0, 0)
odbc.c:3463:SQLExecDirect(0x1004cb550, 0x100434950, -3)
prepare_query.c:203:parsing 0 parameters
odbc.c:3211:_SQLExecute(0x1004cb550)
odbc.c:3216:_SQLExecute() starting with state 0
mem.c:615:tds_free_all_results()
util.c:156:Changed query state from IDLE to QUERYING
write.c:140:tds_put_string converting 30 bytes of "??????????????????????????????"
write.c:168:tds_put_string wrote 12 bytes
util.c:156:Changed query state from QUERYING to PENDING
net.c:741:Sending packet
0000 01 01 00 14 00 00 01 00-fd ff fd ff fd ff fd ff |........ ????????|
0010 fd ff fd ff - |????|
token.c:540:tds_process_tokens(0x1004b7c90, 0x7fff5fbff1b4, 0x7fff5fbff1b0, 0x6914)
util.c:156:Changed query state from PENDING to READING
net.c:555:Received header
0000 04 01 00 6a 00 42 01 00- |...j.B..|
net.c:609:Received packet
0000 04 01 00 6a 00 42 01 00-aa 56 00 66 00 00 00 01 |...j.B.. ?V.f....|
0010 0f 1a 00 49 00 6e 00 63-00 6f 00 72 00 72 00 65 |...I.n.c .o.r.r.e|
0020 00 63 00 74 00 20 00 73-00 79 00 6e 00 74 00 61 |.c.t. .s .y.n.t.a|
0030 00 78 00 20 00 6e 00 65-00 61 00 72 00 20 00 27 |.x. .n.e .a.r. .'|
0040 00 fd ff 27 00 2e 00 0b-43 00 4f 00 4c 00 4f 00 |.??'.... C.O.L.O.|
0050 2d 00 53 00 51 00 4c 00-2d 00 30 00 32 00 00 01 |-.S.Q.L. -.0.2...|
0060 00 fd 02 00 fd 00 00 00-00 00 |.?..?... ..|
token.c:555:processing result tokens. marker is aa(ERROR)
token.c:122:tds_process_default_tokens() marker is aa(ERROR)
token.c:2588:tds_process_msg() reading message 102 from server
token.c:2661:tds_process_msg() calling client msg handler
odbc.c:2270:msgno 102 20003
token.c:2674:tds_process_msg() returning TDS_SUCCEED
token.c:555:processing result tokens. marker is fd(DONE)
token.c:2339:tds_process_end: more_results = 0
was_cancelled = 0
error = 1
done_count_valid = 0
token.c:2355:tds_process_end() state set to TDS_IDLE
util.c:156:Changed query state from READING to IDLE
token.c:2370: rows_affected = 0
util.c:104:logic error: cannot change query state from IDLE to PENDING
odbc.c:3534:odbc_process_tokens: tds_process_tokens returned 1
odbc.c:3535: result_type=4052, TDS_DONE_COUNT=0, TDS_DONE_ERROR=2
odbc.c:3575:odbc_process_tokens: row_count=-1
odbc.c:3374:_SQLExecute: odbc_process_tokens returned result_type 4052
error.c:517:SQLGetDiagRec(3, 0x1004cb550, 1, 0x7fff5fbfee8c, 0x7fff5fbfee94, 0x7fff5fbfeea0, 1023, 0x7fff5fbfee92)
error.c:566:SQLGetDiagRec: "[FreeTDS][SQL Server]Incorrect syntax near '�'."