Naja, so kompliziert ist es dann doch nicht.
Du musst Dir das so vorstellen: Überall in Deinem PC geistern Strings rum. Die sind alle
kodiert, man sagt dazu auch Byte-String in Python. Z.B. ASCII, ISO-8859-1, LATIN-1, UTF-8, UTF-16, usw. Diese Encodings definieren in einer Tabelle, welcher Integerwert auf welches Zeichen verweist. Im ASCII-Zeichensatz verweist der Wert 65 bspw. auf das `A`.
Unicode (im Python-Sinne) kannst Du Dir nun vorstellen als eine spezielle Art von String, die *nur* während der Laufzeit eines Programmes im Speicher existiert. Du kannst das nicht serialisieren, ohne es explizit oder implizit in einen kodierten Zeichensatz zu wandeln (kleine "Lüge", aber nimm es mal so hin).
Daneben können im Speicher aber auch (kodierte) Byte-Strings existieren, das macht es "kompliziert". Es gibt (in Python2) also zwei Arten von Strings: Byte-Strings und Unicode-Strings.
Wenn Module nun interagieren sollen, wie eben Dein eigenes mit dem SQLite-Modul, ist es praktisch, dafür festzulegen, welche Art von String benutzt werden soll. Wählte man dafür Byte-Strings, so müsste man ja noch festlegen, welches Encoding! Davon gibt es leider so viele und nicht alle decken alle Zeichen ab... also ist es doch praktischer, Unicode-Strings zu "fordern". Damit obliegt es Dir, als "Benutzer" einer Lib, Deine Strings in Unicode zu wandeln, bevor Du die Funktionalität der Lib benutzen kannst.
Stell Dir das so ähnlich vor, wie bei der Erfindung des Geldes: Vorher tauschte man Gegenstände aus, die nicht immer zueinander passten - durch das Konzept des Geldes hat man ein universelles Gut entwickelt, in dem sich alle Geschäfte problemlos abwickeln lassen - theoretisch natürlich
Unicode ist eben eine Art von String, die universell austauschbar ist. Daher solltest Du selber alle Deine Module ebenfalls (intern) auf Unicode umstellen. Probleme treten halt immer da auf, wo Daten von "irgend wo" außerhalb des Speichers auftauchen, also z.B. beim Laden aus einer Datei, beim Pipen aus einer Shell, bei der Eingabe durch den Benutzer, bei der Angabe von String-Literalen in Deinem Programm, usw. An diesen Stellen muss man die Byte-Strings dekodieren (= in Unicode-Strings wandeln).
Es gibt übrigens aus Module, die selber eben kein Unicode unterstützen, das Encoding nicht festlegen oder es nicht spezifizierbar machen, etwa das `csv`-Modul. Mit solchen Modulen hat man dann oftmals Ärger und muss einen Workaround bauen.
Vielleicht ist Dir nun schon aufgefallen, wo da das Problem liegt: Man muss das Encoding der Daten kennen - das macht es "mühsam"

Denn man kann das Encoding von Daten nicht deterministisch herausfinden, man kann maximal raten. Also ist es auch sinnvoll, bei den eigenen Schnittstellen eines Programms, zu spezifizieren, welche Art von Encoding erwartet bzw. akzeptiert wird. utf-8 wird von vielen deswegen gewählt, weil es (fast) den gesamten Unicode-Umfang abdeckt, d.h. Du kannst so ziemlich alle Zeichen in allen Sprachen verwenden. Bei ASCII hingegen hapert es bereits bei deutschen Umlauten und Sonderzeichen
So, ich hoffe das war jetzt erhellend und nicht verstörend
