2017-02-21 1 views
2

Ich habe versucht, die Anzahl der Vorkommen eines Teilstrings in einem Zeichenfeld einer Datenbank (PostgreSQL, Pyodbc, Python 3.4.4, Windows 7) zu zählen. War das Zeichenfeld jedoch größer als 511, gab count() immer Null zurück. Erst nach dem "Ausführen von etwas" mit der zurückgegebenen Zeichenfolge (z. B. Zugriff auf die Zeichenfolge bei Index 0 oder Verwendung von print() zum Anzeigen der Zeichenfolge) gab count() den erwarteten Wert zurück. Bei Saiten der Länge 511 oder weniger gab es keine Probleme.Warum gibt count() 0 zurück, wenn mit pyodbc auf ein Zeichenfeld größer als 511 zugegriffen wird?

Das Weiteren der Größe der (512 oder größer) Zeichenfolge scheint das Beispiel unten zu verändern, zu sehen.

Dieses Problem scheint mit PostgreSQL, SQLite und Oracle auftreten, wenn Pyodbc verwenden. Ich konnte es nicht mit psycopg2 reproduzieren.

So ist es ein Bug in Pyodbc? Oder ist es eine Art von Optimierung und count() hat Probleme damit? (Andere Funktionen scheinen in Ordnung zu sein, zum Beispiel len().)

Das folgende Python-Skript reproduziert dieses Problem mit PostgreSQL, SQLite-ODBC oder Oracle. Es wird zwei Tabellen erstellen, Text einfügen und versuchen, die Funktion count() für die zurückgegebenen Daten verwenden.

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() 

UPDATE: das Problem war mit Pyodbc 3.0.10. Version 4.0.11 behebt das Problem.

+1

Verwenden Sie Pyodbc 4.0.11? –

+0

Ich verwendete pyodbc Version 3.0.10. Vielen Dank. Also anscheinend ist es ein Fehler und 4.0.11 befasst sich mit diesem Problem. – segmentationfault

Antwort

2

Das Problem wird in Pyodbc 4.0.11 behoben.

So scheint es hierbei um ein Problem mit früheren Versionen Pyodbc war (I 3.0.10 wurde mit).

Verwandte Themen