sql >> Database teknologi >  >> RDS >> Oracle

Kan ikke læse SQL-tabel korrekt i python:varchar-kolonner importeret som kommaseparerede tegn/tupler

Dette ser ud til at være et problem, når du bruger jaydebeapi med jpype . Jeg kan gengive dette, når jeg forbinder til en Oracle db på samme måde, som du gør (i mit tilfælde Oracle 11gR2, men da du bruger ojdbc8.jar , det sker vel også med andre versioner).

Der er forskellige måder, du kan løse dette på:

Skift din forbindelse

Da fejlen kun ser ud til at opstå i en bestemt kombination af pakker, er det mest fornuftige at gøre at forsøge at undgå disse og dermed fejlen helt.

  1. Alternativ 1:Brug jaydebeapi uden jpype :

    Som nævnt observerer jeg kun dette, når jeg bruger jaydebeapi med jpype . Men i mit tilfælde jpype er slet ikke nødvendig. Jeg har .jar fil lokalt, og min forbindelse fungerer fint uden:

    import jaydebeapi as jdba
    import pandas as pd
    import os
    
    db_host = 'db.host.com'
    db_port = 1521
    db_sid = 'YOURSID'
    
    jar=os.getcwd()+'/ojdbc6.jar'
    
    conn = jdba.connect('oracle.jdbc.driver.OracleDriver', 
                    'jdbc:oracle:thin:@' + db_host + ':' + str(db_port) + ':' + db_sid, 
                    {'user': 'USERNAME', 'password': 'PASSWORD'}, 
                    jar
                    )
    
    df_jay = pd.read_sql('SELECT * FROM YOURSID.table1', conn)
    
    conn.close()
     

    I mit tilfælde fungerer dette fint og opretter datarammerne normalt.

  2. Alternativ 2:Brug cx_Oracle i stedet:

    Problemet opstår heller ikke, hvis jeg bruger cx_Oracle for at oprette forbindelse til Oracle db:

    import cx_Oracle
    import pandas as pd
    import os
    
    db_host = 'db.host.com'
    db_port = 1521
    db_sid = 'YOURSID'
    
    dsn_tns = cx_Oracle.makedsn(db_host, db_port, db_sid)
    cx_conn = cx_Oracle.connect('USERNAME', 'PASSWORD', dsn_tns)
    
    df_cxo = pd.read_sql('SELECT * FROM YOURSID.table1', con=cx_conn)
    
    cx_conn.close()
     

    Bemærk:For cx_Oracle for at arbejde skal du have Oracle Instant Client installeret og korrekt opsat (se f.eks. cx_Oracle-dokumentation til Ubuntu ).

Ret dataramme efter kendsgerningen:

Hvis du af en eller anden grund ikke kan bruge ovenstående forbindelsesalternativer, kan du også transformere din dataramme.

  1. Alternativ 3:Deltag i tuple-indgange:

    Du kan bruge ''.join() at konvertere tupler til strenge . Du skal gøre dette for indtastningerne og kolonnenavnene.

    # for all entries that are not None, join the tuples
    for col in df.select_dtypes(include=['object']).columns:
        df[col] = df[col].apply(lambda x: ''.join(x) if x is not None else x)
    
    # also rename the column headings in the same way
    df.rename(columns=lambda x: ''.join(x) if x is not None else x, inplace=True)
     
  2. Alternativ 4:skift dtype af kolonner:

    Ved at ændre dtype af en berørt kolonne fra object til string , vil alle poster også blive konverteret. Bemærk, at dette kan have uønskede bivirkninger, som f.eks. ændre None værdier til strengen <N/A> . Du bliver også nødt til at omdøbe kolonneoverskrifterne separat, som ovenfor.

    for col in df.select_dtypes(include=['object']).columns:
        df[col] = df[col].astype('string')
    
    # again, rename headings
    df.rename(columns=lambda x: ''.join(x) if x is not None else x, inplace=True)
     

Alle disse burde give mere eller mindre den samme df til sidst (bortset fra dtypes og mulig erstatning af None værdier):

+---+---------+---------+---------+ | | COLUMN1 | COLUMN2 | COLUMN3 | +---+---------+---------+---------+ | 1 | test | test2 | 1 | +---+---------+---------+---------+ | 2 | foo | bar | 100 | +---+---------+---------+---------+


  1. SQL group_concat-funktion i SQL Server

  2. Hvordan forespørger man efter null-værdier i json-felttypen postgresql?

  3. Simpel tabelforespørgselssyntaksfejl?

  4. dynamisk tegning af polylinjer på googlemaps ved hjælp af php/mysql