Saya baru-baru ini dibingungkan oleh masalah berikut dalam database SQLite: Saya memiliki tabel dengan dua baris yang tampaknya identik. Namun, pernyataan berikut hanya mengambil satu dari dua baris:

SELECT "mycolumn" FROM "mytable" WHERE "mycolumn" == 'identical values';

Rupanya, nilai dalam "mycolumn" identik (mereka bahkan memiliki nilai HEX() yang sama). Namun, saya menemukan bahwa tipe data mereka berbeda:

SELECT "mycolumn", TYPEOF("mycolumn"), QUOTE("mycolumn") FROM "mytable";

Memberi saya BLOB di satu baris, TEKS di baris lainnya.

Bagaimana SQLite menentukan apakah itu akan menyimpan nilai sebagai BLOB daripada TEXT? Saya membuat database menggunakan python2.7-sqlite3 (yang membuat baris BLOB), lalu menambahkan baris "identik" menggunakan sqlitebrowser. Namun, saya ingin dapat memaksa python untuk menggunakan tipe TEXT (atau menemukan cara untuk membuat perbandingan dengan BLOB). Apakah ada cara seperti itu?

0
fourmiant 19 Agustus 2017, 06:26

2 jawaban

Jawaban Terbaik

SQLite menyimpan nilai dengan tipe data yang Anda berikan. (Mungkin ada perubahan karena afinitas kolom, tetapi ini tidak pernah memengaruhi gumpalan.)

Jika Anda ingin memasukkan nilai teks, ubah kode Python Anda untuk memasukkan nilai teks (dengan jenis yang tepat).

Untuk memperbaiki nilai dalam database, cukup tulis ulang dengan tipe yang diubah:

UPDATE MyTable
SET MyColumn = CAST(MyColumn AS TEXT)
WHERE typeof(MyColumn) = 'blob';
0
CL. 19 Agustus 2017, 08:12

Sebagai pelengkap jawaban CL., berikut adalah kode python2 minimal yang dapat membantu memahami bagaimana tipe yang disimpan atau diambil ditentukan:

#!/usr/bin/python2
# -*- coding: utf-8 -*-
"""
"""
import sqlite3

c = sqlite3.connect (':memory:')
cc=c.cursor()
cc.execute (''' CREATE TABLE t (a TEXT);''') 

def insert_value (a):
    #Depending on type (a), the stored data type will be different:
    #   TEXT for str or unicode
    #   BLOB for buffer
    cc.execute (''' INSERT INTO t (a) VALUES (?); ''', (a,))
    c.commit ()

## writing into the database: 
print ('Storing a string will store it as TEXT.')
insert_value ('some value')
print ('Storing a buffer will store it as BLOB.')
insert_value (buffer ('some value'))

def read_values ():
    ## reading from the database: the retrieved value only depends
    ## of sqlite3.text_factory, not on the stored type
    cc.execute (''' SELECT rowid, a, TYPEOF(a) FROM t; ''')
    for rowid, retrieved_a, typeof_stored_a in cc.fetchall ():
        print ('%d: type of retr. value: %s; type of stored value: %s'%(
            rowid,
            type(retrieved_a), 
            typeof_stored_a))

print ('\nUsing text_factory <buffer>: BLOB -> buffer; TEXT -> buffer')
c.text_factory = buffer # (=== sqlite3.Binary)
read_values ()

print ('\nUsing text_factory <str>: BLOB -> buffer; TEXT -> str')
c.text_factory = str
read_values ()
c.close ()

Keluaran:

Storing a string will store it as TEXT.
Storing a buffer will store it as BLOB.

Using text_factory <buffer>: BLOB -> buffer; TEXT -> buffer
1: type of retr. value: <type 'buffer'>; type of stored value: text
2: type of retr. value: <type 'buffer'>; type of stored value: blob

Using text_factory <str>: BLOB -> buffer; TEXT -> str
1: type of retr. value: <type 'str'>; type of stored value: text
2: type of retr. value: <type 'buffer'>; type of stored value: blob
1
fourmiant 19 Agustus 2017, 10:09