Проблема с кодировкой для телеграм бота
я создал тг бота и по команде /categories он должен был выдать список категорий которые есть в базе данных. Они выдаются но, только русские слова выдаются кракозябрами. Я понимаю, что дело в сбое кодировке, но я не могу определить где именно сбой и как решить проблему.

Пробовал поменять через category.encode('1251'), не помогло. В терминале Visual studio поставил кодировку 1251, тоже не помогло. Пытался на линуксе в пайчарм, но пайчарм не поддерживает sql код. Далее я приведу свой код, но поясню. У меня есть 3 файла: createdb.sql - создаёт мою БД, categories.py - работает с моими категориями, db.py - уже непосредственно работа с БД. И я не понимаю где может быть сбой кодировки.
1. createdb.sql
codename varchar(255) primary key,
daily_limit integer
);
create table category(
codename varchar(255) primary key,
name varchar(255),
is_base_expense boolean,
aliases text
);
create table expense(
id integer primary key,
amount integer,
created datetime,
category_codename integer,
raw_text text,
FOREIGN KEY(category_codename) REFERENCES category(codename)
);
insert into category (codename, name, is_base_expense, aliases)
values
("products", "продукты", true, "еда"),
("coffee", "кофе", true, ""),
("dinner", "обед", true, ""),
("cafe", "кафе", true, ""),
("transport", "общ. транспорт", false, ""),
("taxi", "такси", false, ""),
("phone", "телефон", false, ""),
("books", "книги", false, ""),
("internet", "интернет", false, ""),
("subscriptions", "подписки", false, "подписка"),
("other", "прочее", true, "");
category = category.encode('1251')
insert into budget(codename, daily_limit) values ('base', 200);
2.categories.py
import db
# Структура категорий
class Category(NamedTuple):
codename: str
name: str
is_base_expense: bool
aliases: List[str]
class Categories:
def __init__(self):
self._categories = self._load_categories()
# Возвращает справочник категорий расходов из БД
def _load_categories(self) -> List[Category]:
categories = db.fetchall(
"category", "codename name is_base_expense aliases".split()
)
categories = self._fill_aliases(categories)
return categories
# Заполняет по каждой категории aliases, то есть возможные названия этой категории
def _fill_aliases(self, categories: List[Dict]) -> List[Category]:
categories_result = []
for index, category in enumerate(categories):
aliases = category["aliases"].split(",")
aliases = list(filter(None, map(str.strip, aliases)))
aliases.append(category["codename"])
aliases.append(category["name"])
categories_result.append(Category(
codename=category['codename'],
name=category['name'],
is_base_expense=category['is_base_expense'],
aliases=aliases
))
return categories_result
# Возвращает справочник категорий
def get_all_categories(self) -> List[Dict]:
return self._categories
# Возвращает категорию по одному из её alias
def get_category(self, category_name: str) -> Category:
finded = None
other_category = None
for category in self._categories:
if category.codename == "other":
other_category = category
for alias in category.aliases:
if category_name in alias:
finded = category
if not finded:
finded = other_category
return finded
3. db.py
from typing import Dict, List, Tuple
import sqlite3
conn = sqlite3.connect("finance.db")
cursor = conn.cursor()
def insert(table: str, column_values: Dict):
columns = ', '.join( column_values.keys() )
values = [tuple(column_values.values())]
placeholders = ", ".join( "?" * len(column_values.keys()) )
cursor.executemany(
f"INSERT INTO {table} "
f"({columns}) "
f"VALUES ({placeholders})",
values)
conn.commit()
def fetchall(table: str, columns: List[str]) -> List[Tuple]:
columns_joined = ", ".join(columns)
cursor.execute(f"SELECT {columns_joined} FROM {table}")
rows = cursor.fetchall()
result = []
for row in rows:
dict_row = {}
for index, column in enumerate(columns):
dict_row[column] = row[index]
result.append(dict_row)
return result
def delete(table: str, row_id: int) -> None:
row_id = int(row_id)
cursor.execute(f"delete from {table} where id={row_id}")
conn.commit()
def get_cursor():
return cursor
# Инициализация БД
def _init_db():
with open("createdb.sql", "r") as f:
sql = f.read()
cursor.executescript(sql)
conn.commit()
# Проверяет, инициализирована ли БД, если нет — инициализирует
def check_db_exists():
cursor.execute("SELECT name FROM sqlite_master "
"WHERE type='table' AND name='expense'")
table_exists = cursor.fetchall()
if table_exists:
return
_init_db()
check_db_exists()
Помогите пожалуйста решить проблему!