python - 为什么使用 pyodbc 访问大于 511 的字符字段时 count() 返回 0?

标签 python postgresql sqlite pyodbc

我试图计算数据库字符字段中子字符串的出现次数(PostgreSQL、pyodbc、Python 3.4.4、Windows 7)。但是当字符字段大于 511 时,count() 总是返回零。仅在对返回的字符串“执行某些操作”之后(例如访问索引 0 处的字符串或使用 print() 查看该字符串),count() 才会返回预期值。长度为 511 或更短的字符串没有问题。

此外,字符串的大小(512 或更大)似乎发生了变化,请参见下面的示例。

使用 pyodbc 时,PostgreSQL、SQLite 和 Oracle 似乎会出现此问题。我无法使用 psycopg2 重现它。

那么,这是 pyodbc 中的一个错误吗?或者是某种优化,而 count() 确实有问题? (其他函数似乎也可以,例如 len()。)

以下 Python 脚本将使用 PostgreSQL、SQLite-ODBC 或 Oracle 重现此问题。 它将创建两个表,插入文本并尝试对返回的数据使用函数 count()。

import pyodbc
import sys

#conn   = pyodbc.connect('driver={SQLite3 ODBC Driver}; server=localhost; database=D:\\test.db;')
#conn   = pyodbc.connect('DSN=test-oracle;uid=xx;pwd=xx')
conn   = pyodbc.connect('DSN=test-postgresql;uid=xx;pwd=xx')
cursor = conn.cursor()
with conn.cursor() as cursor:

    cursor.execute("create table testtable511 (txt char(511) default ' ' primary key not NULL);")
    cursor.execute("insert into testtable511 (txt) values ('"+511*"t"+"');")
    cursor.execute("create table testtable512 (txt char(512) default ' ' primary key not NULL);")
    cursor.execute("insert into testtable512 (txt) values ('"+512*"t"+"');")

    cursor.execute('select * from testtable511')
    data511  = cursor.fetchone()
    print('511')
    print(80*'#')
    # count is 511, size is 560
    print('counting t before "accessing" string of testtable511:     ', data511[0].count('t'))
    print('size of string before "accessing" string of testtable511: ', sys.getsizeof( data511[0] ))
    data511[0][0]
    # count is 511, size is 560
    print('counting t after "accessing" string of testtable511:      ',  data511[0].count('t'))
    print('size of string after "accessing" string of testtable511:  ',  sys.getsizeof( data511[0] ))
    print(80*'#')

    print()

    cursor.execute('select * from testtable512')
    data512 = cursor.fetchone()
    print('512')
    print(80*'#')
    # count is 0, size is 1106
    print('counting t before "accessing" string of testtable512:     ', data512[0].count('t'))
    print('size of string before "accessing" string of testtable512: ', sys.getsizeof( data512[0] ))
    data512[0][0]
    # count is 512, size is 593
    print('counting t after "accessing" string of testtable512:      ', data512[0].count('t'))
    print('size of string after "accessing" string of testtable512:  ', sys.getsizeof( data512[0] ))
    print(80*'#')

    cursor.execute("drop table testtable511;")
    cursor.execute("drop table testtable512;")

conn.close()

更新:问题出在 pyodbc 3.0.10 上。 4.0.11 版本修复了该问题。

最佳答案

该问题已在 pyodbc 4.0.11 中修复。

看来这是早期 pyodbc 版本的一个错误(我使用的是 3.0.10)。

关于python - 为什么使用 pyodbc 访问大于 511 的字符字段时 count() 返回 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42369502/

相关文章:

python - 使用 django-rest-framework-simple-jwt 中的三个字段进行身份验证

python - 将 Python Pool 与上下文管理器一起使用或关闭并加入

PostgreSQL array_agg 命令

ruby-on-rails - Rails/POSTGRES ISDATE 函数

当用户和设备存储在同一个表中并且关联存储在另一个表中时,SQL/SQLite 检索属于用户的设备列表

python - matplotlib 和 Qt : mouse press event. key 总是 None

python - 在 doxygen 代码片段中插入空行

Postgresql函数执行错误

ios - 体系结构 i386 : "_sqlite3_open", 的 undefined symbol 引用自:

c++ - 在 C++ 中将 sqlite 结果转换为 std::string