Написание df с таким столбцом списка
df = pl.DataFrame({'a': [1,2,3], 'b':[['A','B'], ['C', 'D'], ['E', 'F']]})
df.write_database(
"test", "sqlite:///test.db",
if_table_exists = "replace",
)
работает нормально, но потом работает
pl.read_database_uri(query = "SELECT * FROM test", uri = "sqlite://test.db")
выдает ошибку
RuntimeError: Invalid column type Blob at index: 1, name: b
Кажется, я не могу обойти это, используя engine_options
в write_database
, чтобы указать, что мне нужно поле списка (а не большой двоичный объект), или используя schema_overrides
в read_database_uri
. Каков правильный способ записи/чтения такого типа фрейма данных со столбцами списка?
🤔 А знаете ли вы, что...
Python поддерживает множество парадигм программирования, включая процедурное, объектно-ориентированное и функциональное программирование.
Я считаю, что в вашем случае вам нужно будет сохранить список строк как BLOB в MySQL lite, а затем каким-то образом декодировать байты обратно в список. Однако есть две проблемы:
connectorx
не может читать столбцы BLOB, поэтому вам нужно переключиться на adbc
adbc
непонятно, как преобразовать BLOB обратно в байты.Таким образом, я бы предложил объединить список строк с любым разделителем и сохранить строки как VARCHAR, а затем преобразовать обратно:
import polars as pl
SEP = "\t"
df = pl.DataFrame({'a': [1,2,3], 'b':[['A','B'], ['C', 'D'], ['E', 'F']]})
# mapping: List[str] -> str
df = df.with_columns(b = pl.col('b').list.join(SEP))
df.write_database(
"test", "sqlite:///test.db",
if_table_exists = "replace",
)
ff = pl.read_database_uri(query = "SELECT a,b FROM test",
uri = "sqlite://test.db",
)
# mapping: str -> List[str]
ff = ff.with_columns(pl.col('b').str.split(SEP))
Альтернативно:
Или сериализуйте столбец в json и снова сохраните его в базе данных как VARCHAR, а затем десериализуйте обратно.
import json
import polars as pl
df = pl.DataFrame({'a': [1,2,3], 'b':[['A','B'], ['C', 'D'], ['E', 'F']]})
# dump to json
f = lambda x: json.dumps(list(x))
df = df.with_columns(b = pl.col('b').apply(f))
df.write_database(
"test", "sqlite:///test.db",
if_table_exists = "replace",
)
ff = pl.read_database_uri(query = "SELECT a,b FROM test",
uri = "sqlite://test.db",
)
ff = ff.with_columns(pl.col('b').str.json_decode())
Альтернатива 2:
Подготовьте столбец, преобразовав его в двоичный объект, прежде чем сохранять его в базе данных sql. Столбец будет сохранен как BLOB.
import pickle
import polars as pl
df = pl.DataFrame({'a': [1,2,3], 'b':[['A','B'], ['C', 'D'], ['E', 'F']]})
# dump column to binary object
df = df.with_columns(b = pl.col('b').apply(pickle.dumps))
df.write_database(
"test", "sqlite:///test.db",
if_table_exists = "replace",
)
ff = pl.read_database_uri(query = "SELECT a,b FROM test",
uri = "sqlite://test.db",
engine='adbc', # need to use adbc engine instead of standard
)
ff = ff.with_columns(pl.col('b').apply(pickle.loads))