Rozsáhlá modernizace hardwarové infrastruktury Základních registrů měla zabránit výpadkům digitálních služeb státu. Dnešnímu výpadku nezabránila.
Čínský startup Kimi představil open-source model umělé inteligence Kimi K2.5. Nová verze pracuje s textem i obrázky a poskytuje 'paradigma samosměřovaného roje agentů' pro rychlejší vykonávání úkolů. Kimi zdůrazňuje vylepšenou schopnost modelu vytvářet zdrojové kódy přímo z přirozeného jazyka. Natrénovaný model je dostupný na Hugging Face, trénovací skripty však ne. Model má 1 T (bilion) parametrů, 32 B (miliard) aktivních.
V Raspberry Pi OS lze nově snadno povolit USB Gadget Mode a díky balíčku rpi-usb-gadget (CDC-ECM/RNDIS) mít možnost se k Raspberry Pi připojovat přes USB kabel bez nutnosti konfigurování Wi-Fi nebo Ethernetu. K podporovaným Raspberry Pi připojeným do USB portu podporujícího OTG.
Konference Installfest 2026 proběhne o víkendu 28. a 29. března v budově FELu na Karlově náměstí v Praze. Přihlásit přednášku nebo workshop týkající se Linuxu, otevřených technologií, sítí, bezpečnosti, vývoje, programování a podobně lze do 18. února 0:15.
Fedora Flock 2026, tj. konference pro přispěvatele a příznivce Fedory, bude opět v Praze. Proběhne od 14. do 16. června. Na Flock navazuje DevConf.CZ 2026, který se uskuteční 18. a 19. června v Brně. Organizátoři konferencí hledají přednášející, vyhlásili Call for Proposals (CfP).
Z80-μLM je jazykový model 'konverzační umělé inteligence' optimalizovaný pro běh na 8-bitovém 4Mhz procesoru Z80 s 64kB RAM, technologii z roku 1976. Model používá 2-bitovou kvantizaci a trigramové hashování do 128 položek, což umožňuje zpracování textu i při velmi omezené paměti. Natrénovaný model se vejde do binárního souboru velkého pouhých 40 KB. Tento jazykový model patrně neprojde Turingovým testem 😅.
Digitální a informační agentura (DIA) na přelomu roku dokončila rozsáhlou modernizaci hardwarové infrastruktury základních registrů. Projekt za 236 milionů korun by měl zabránit výpadkům digitálních služeb státu, tak jako při loňských parlamentních volbách. Základní registry, tedy Registr práv a povinností (RPP), Informační systém základních registrů (ISZR) a Registr obyvatel (ROB), jsou jedním z pilířů veřejné správy. Denně
… více »Evropská komise (EK) zahájila nové vyšetřování americké internetové platformy 𝕏 miliardáře Elona Muska, a to podle unijního nařízení o digitálních službách (DSA). Vyšetřování souvisí se skandálem, kdy chatbot s umělou inteligencí (AI) Grok na žádost uživatelů na síti 𝕏 generoval sexualizované fotografie žen a dětí. Komise o tom dnes informovala ve svém sdělení. Americký podnik je podezřelý, že řádně neposoudil a nezmírnil rizika spojená se zavedením své umělé inteligence na on-line platformě.
Bratislava OpenCamp pokračuje vo svojej tradícii a fanúšikovia otvorených technológií sa môžu tešiť na 4. ročník, ktorý sa uskutoční 25. 4. 2026 na FIIT STU v Bratislave. V súčasnosti prebieha prihlasovanie prednášok a workshopov – ak máte nápad, projekt, myšlienku, o ktoré sa chcete podeliť s komunitou, OpenCamp je správne miesto pre vás.
Krádež není inovace (Stealing Isn't Innovation). Koalice umělců, spisovatelů a tvůrců protestuje proti používání autorsky chráněných děl velkými technologickými společnostmi pro trénování AI systémů bez povolení či kompenzace.
Odkazy
Keď som s djangom začínal nemal som ORM vôbec rád. Bolo hrozne obmedzené a veľa vecí bolo nutné napísať v surovom SQL. Postupne sa každou verziou ORM zlepšuje a ja môžem vyhadzovať rôzne hacky. Dnešný blog bude o nahradení django-qsstats-magic funkciami priamo z django ORM.
Všetky ukážky budem robiť na modeli používateľov z django.contrib.auth. Minimálna verzia djanga je 1.8. Databáza ľubovoľná (MySQL nepovažujem za databázu), ja som pre ukážky použil SQLite.
Ak je všetko nastavené správne tak by nasledujcúi kód v python shelli mal zobraziť zoznam používateľov:
User.objects.all() # [<User: admin>, ...]
Na select časového radu využijeme jednu nezdokumentovanú časť API (žiaden strach, aj zmeny v nezdokumentovaných API sú minimálne pol roka dopredu známe, u zdokumentovaných zvyčajne niekoľko rokov). Začneme importmi (v nasledujúcich ukážkach budem predpokladať, že sú tieto moduly importované).
from collections import namedtuple from django.contrib.auth import get_user_model from django.db.models import Count from django.db.models.expressions import DateTime from django.utils import timezone User = get_user_model()
Nasledujúci zápis pre každý riadok vypočíta (annotate) deň (date_joined je dátum a čas, chceme zoskupiť podľa dní), zoradí podľa dátumu (order_by) a vráti len vybrané stĺpce (values_lsit).
ts = (User.objects
.annotate(time_value=DateTime('date_joined', 'day', timezone.get_current_timezone()))
.values_list('time_value')
.order_by('time_value'))
# ts = [(datetime.datetime(2015, 9, 17, 0, 0, tzinfo=<DstTzInfo 'Europe/Bratislava' CEST+2:00:00 DST>),)...
Presný SQL dotaz sa dá vypísať pomocou print(ts.query), pre SQLite vyzerá takto:
SELECT django_datetime_trunc('day', "auth_user"."date_joined", Europe/Bratislava) AS "time_value"
FROM "auth_user"
ORDER BY "time_value" ASC
Funkciu django_datetime_trunc do SQlite registruje django. Vďaka nej je možné aj v tak blbej databáze ako SQlite vykonať operáciu trunc vrátane podpory časovej zóny.
Postačí už len priadať agregačnú funkciu napr. počet registrovaných používateľov (Count('id')) a ORM nám vyhodí zoznam dvojíc - dátum a počet registrácií v daný deň:
ts = (User.objects
.annotate(time_value=DateTime('date_joined', 'day', timezone.get_current_timezone()))
.values_list('time_value')
.order_by('time_value')
.annotate(count=Count('id')))
# ts = [(deň, 6), (deň, 1), ...
# print(ts.query)
SELECT
django_datetime_trunc('day', "auth_user"."date_joined", Europe/Bratislava) AS "time_value",
COUNT("auth_user"."id") AS "count"
FROM "auth_user"
GROUP BY django_datetime_trunc('day', "auth_user"."date_joined", Europe/Bratislava)
ORDER BY "time_value" ASC
Keďže my programátori sme leniví a nechceme písať celý tento bordel znovu a znovu je fajn obaliť si to do funkcie.
def time_series(qs, date_field, aggregate, interval):
if not isinstance(aggregate, dict):
aggregate = {'aggregate': aggregate}
SeriesRecord = namedtuple('SeriesRecord', ['time_value'] + aggregate.keys())
qs = (qs
.annotate(time_value=DateTime(date_field, interval, timezone.get_current_timezone()))
.values_list('time_value')
.order_by('time_value')
.annotate(**aggregate))
return [SeriesRecord(*val) for val in qs]
Ešte spôsob použitia:
time_series(
User.objects.all(),
date_field='date_joined',
aggregate=Count('id'), # alebo aggregate={'count': Count('id')}
interval='day'
)
[SeriesRecord(time_value=datetime.datetime(2015, 9, 17, 0, 0, tzinfo=<DstTzInfo 'Europe/Bratislava' CEST+2:00:00 DST>), aggregate=6), SeriesRecord(time_value=datetime.datetime(2015, 9, 24, 0, 0, tzinfo=<DstTzInfo 'Europe/Bratislava' CEST+2:00:00 DST>), aggregate=1), SeriesRecord(time_value=datetime.datetime(2015, 9, 28, 0, 0, tzinfo=<DstTzInfo 'Europe/Bratislava' CEST+2:00:00 DST>), aggregate=1), SeriesRecord(time_value=datetime.datetime(2015, 9, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Bratislava' CEST+2:00:00 DST>), aggregate=1), SeriesRecord(time_value=datetime.datetime(2015, 10, 1, 0, 0, tzinfo=<DstTzInfo 'Europe/Bratislava' CEST+2:00:00 DST>), aggregate=1)]
K dokonalosti chýba už len jedna drobnosť - vyplnenie medzier. Po tejto mini drobnosti nám už nič nebráni v okopírovaní change baru z githubu 
Programátori asi poznajú to známe 20:80, v tomto prípade vypnenie medzier bolo práve tých 80 (týmto pozdravujem ľudí ktorí vymysleli letný a zimný čas, fakt ste mi uľahčili prácu
).
Výsledný kód aj s vypĺňaním medzier mám zverejnený na githube.
Tiskni
Sdílej:
Databáza ľubovoľná (MySQL nepovažujem za databázu), ja som pre ukážky použil SQLite.Uff.
Mysql má veľa vecí implementovaných akože. SQLite sa na nič nehraje, je to embedded blbosť a tým to končí.
Urobiť ORM nad MySQL je na vytrhanie vlasov. Chcem napr. cez ORM získať komentáre najnovších 10 užívateľov:
Comment.objects.filter(author__in=User.objects.order_by('-id')[:10])
MySQL sa síce tvári, že subselecty podporuje, ale v subselecte sa nedá použiť napr. limit. SQL kompilátor musí vziať do úvahy toto obmedzenie a vykonať najskôr vnútorný select a potom použiť operátor IN s vymenovanými hodnotami. Lenže mysql má akosi limit na vymenované hodnoty. Korektne sa to vyriešiť nedá, môžem len dúfať že to väčšinou pôjde.
Kapitolou samou o sebe je v mysql kódovanie. Do varchar(100) nemôžem vložiť 100 znakov, ale dĺžka je v bytoch. Ako to validovať pred uložením? No korektne veľmi ťažko. Čo vlastne zobraziť užívateľovi? Používateľ zadá 80 unicode znakov a validácia bude kričať, človeče pozor, môžeš max 100 bytov, ale spočítaj si byty nie znaky.
MySQL je proste typická ukážka "celé zle". Nevadí mi keď je niečo sprosté. Vadí mi keď je implementácia odfláknutá a nerieši špeciálne situácie.
Pozastavil jsem se nad tim, ze nejdrive reknete, ze mysql neni databaze, a pak si vyberete pouziti sqlite. Vyznelo to vtipne. Ale uznavam, ze pro vas ucel sqlite plne dostacuje. Osobne preferuji postgresql. Je to open source projekt se super komunitou a v poslednich verzich ma i funkce, ktere drive byly vysadou relativne drahych alternativ.
V príkladoch zvyčajne volím SQLite, ak niekto chce narýchlo vyskúšať kód nemusí nič riešiť.
Konkrétne na MySQL nadávam pretože mám rád ľudí
Nedávno sme v práci použili na väčšom projekte MySQL (nie môj výber). Nakoniec sme sa dostali do stavu keď sme riešili viacej MySQL špecifických problémov než zvyšné problémy aplikácie. Takže za pochodu sme migrovali na PostgreSQL. Fakt ak máte možnosť vyhnite sa MySQL. Fakt, fakt, možno na začiatku vyzerá fajn ale tie bugy sa tam nabaľujú a nabaľujú.
Na malé projekty kde si zákazník chce editovať web s max 20 podstránkami používame MySQL ... ale postaršiu verziu. Chcel by som vidieť toho experta ktorý riešil InnoDB. Mať podporovaný fulltext iba v Myisam je na zbláznenie. No čo si mám vybrať, referenčnú integritu, či fulltext?
Veľké fulltextové riešenia ako lucene na web kde príde 10 ľudí denne a má dokopy 20 podstránok je kanón na vrabca.
Postgresql je jasna volba.
Takže za pochodu sme migrovali na PostgreSQL+100
Osobne preferuji postgresql.Vlastne me to ani neprekvapuje, protoze jste jen nekonzistentni 1/2 sudetonemecky blafal. Takze pro Vasi informaci. Postgres byla vyvinuta na statni univerzite a vyvoj byl placen z penez danovych poplatniku. Michael Stonebraker (vedouci toho projektu) je typicky zcela zrejme pripad vysokoskolskeho ucitele, ktery by v privatnim sektoru umrel hlady.
Michael Stonebraker (vedouci toho projektu) je typicky zcela zrejme pripad vysokoskolskeho ucitele, ktery by v privatnim sektoru umrel hlady.Zajimave, ze stihl zalozit/prodat hned nekolik firem.
Autor si stezuje na na problemy s mysql pod ORM.
Nepovažoval by som ich za problémy s ORM. Sú to všeobecné problémy. To, že nemôžem použiť fulltext pri InnoDB nemá s ORM nič spoločné. To, že nastavím poľu dĺžku 100 znakov a databáza mi negarantuje, že tam môžem uložiť 100 znakov nie je problém ORM. Mne to však robí zásadný problém, že nemôžem validovať formulár pred pokusom o uloženie. Nemôžem tomu kto zadáva do poľa nejaký text garantovať akú dĺžku môžem uložiť do db. V žiadnom prípade netolerujem ak mi databáza vyhodí bez príčiny výnimku keď jej dám validný vstup, netolerujem keď mi v tichosti odstrihne znaky v reťazci a už vôbec nie ak mi unicode reťazec odstrihne v polovici znaku.
Problem vidim v pouziti ORM jako zasadne 'problematicke' technologii, jak se vyhnout specifikum jednotlivych databazi.
To netvrdím. Je mi relatívne jedno, či moja aplikácia beži v jedinej správnej db, alebo na všetkom možnom. Stačí mi, že beží s DB ktorú som si nainštaloval na server. ORM používam kvôli úplne iným vlastnostiam a tu sa trochu rozpíšem.
Ako som na začiatku spomínal Django ORM som nemal zo začiatku rád. Bola obmedzená a naučiť sa ju trvalo dlho (porovnateľne dlho s učením sa samotného SQL). V prvom rade nie je to žiadna zázračná vecička ktorú hneď začnete používať a ste majstri sveta. Je to samostatný jazyk nad SQL a jeho učenie trvá aj v prípade znalosti SQL približne rovnakú dobu.
Dlhú dobu som ORM nútil do vecí ktoré neovládalo (použitím metódy extra, alebo v najhoršom prípade napísaním celého raw SQL a obalením do objektov). V súčasnosti to už robím len veľmi výnimočne. Pred pár dňami som robil selecty nad zoznamkou a filtrovanie. Vyšiel z toho dotaz ktorý mal po rozpísaní asi 100 riadkov. Dosť komplikovaný s pár joinmi, pár CASEmi, ale bol presne taký ako by som ho napísal ručne až na názvy aliasov tabuliek. Čas kým som vyskladal dotaz bol porovnateľný s vyskladaním SQL dotazu, zase žiadna zázračna skratka na všetko sa nekoná.
Teraz k silným stránkam: postupne budem skladať trochu zložitejší dotaz:
qs = (Article.objects
.all())
SELECT
"article_article"."id",
"article_article"."title",
"article_article"."slug",
"article_article"."category_id",
"article_article"."perex",
"article_article"."annotation",
"article_article"."content",
"article_article"."author_id",
"article_article"."authors_name",
"article_article"."pub_time",
"article_article"."updated",
"article_article"."published",
"article_article"."top",
"article_article"."image"
FROM "article_article"
WHERE
(
"article_article"."published" = True AND
"article_article"."pub_time" <= 2015-10-04 11:45:29.155657
)
ORDER BY "article_article"."id" DESC
Implicitne sa vyberajú všetky polia. Vo väčšine prípadov je to presne to, čo potrebujem. Ak mi však vadí nejaké pole (napr. content obsahuje priveľký text a na zoznam ho nepotrebujem) stačí použiť defer.
qs = (Article.objects
.defer('content'))
# rovnaké SQL akurát vynechaný stĺpec content
Ak chcem len vybrané stĺpce môžem použiť metódu only:
qs = (Article.objects
.only('title'))
SELECT
"article_article"."id",
"article_article"."title"
FROM "article_article"
WHERE ("article_article"."published" = True AND "article_article"."pub_time" <= 2015-10-04 11:49:48.960429)
ORDER BY "article_article"."id" DESC
U článkov mám štandarnde nastavené filtrovanie publikovaných. Ak by som chcel všetky použijem all_articles
qs = (Article.all_articles
.only('title'))
SELECT
"article_article"."id",
"article_article"."title"
FROM "article_article"
Povedzme, že chcem vo výpise zobraziť aj kategórie:
qs = (Article.all_articles
.select_related('category')
.only('title', 'category'))
SELECT
"article_article"."id",
"article_article"."title",
"article_article"."category_id",
"article_category"."id",
"article_category"."name",
"article_category"."slug",
"article_category"."description"
FROM "article_article"
INNER JOIN "article_category" ON ( "article_article"."category_id" = "article_category"."id" )
Z kategórií sú zase implicintne vyberané všetky stĺpce. Ak by som chcel len názov kategórie tak do only zapíšem namiesto 'category' hodnotu 'category__name'.
Ďalej by som mohol chcieť napríklad zobraziť počet komentárov k článkom:
qs = (Article.all_articles
.select_related('category')
.only('title', 'category__name')
.annotate(comments_count=Count('comments')))
SELECT
"article_article"."id",
"article_article"."title",
"article_article"."category_id",
COUNT("django_comments"."id") AS "comments_count",
"article_category"."id",
"article_category"."name"
FROM "article_article"
LEFT OUTER JOIN "django_comments"
ON ( "article_article"."id" = "django_comments"."object_id" AND ("django_comments"."content_type_id" = 13) )
INNER JOIN "article_category"
ON ( "article_article"."category_id" = "article_category"."id" )
GROUP BY
"article_article"."id",
"article_article"."title",
"article_article"."category_id",
"article_category"."id",
"article_category"."name"
Z príkladov je asi jasné, že django ORM ušetrí veľkú časť písania kódu. O rozmýšľaní to však neplatí 
V poslednom príklade si asi zaslúži jedná časť joinu vysvetlenie. Konkrétne ide o "django_comments"."content_type_id" = 13. Django umožňuje používať generické foreign kľúče. Všetky tabuľky, ktoré django vytvorí majú zároveň záznam v tabuľke django_content_type. Ak mám generické komentáre, ktoré môžu byť ku každému objektu v databáze stačí mi urobiť foreign key content_type_id na túto tabuľku a object_id na tabuľku ku ktorej je priradený komentár.
V príkladoch som pužil dokopy 3 metódy čo je len špička ľadovca. Bez problémov môžem vyskladať omnoho zložitejšie výrazy. Stále mám pomerne slušnú kontrolu nad dotazmi a čo je najdôležitejšie dotazy vyzerajú prakticky rovnako ako keby som ich písal ručne. Dotazy sa reálne spúšťajú až keď cez queryset iterujem.
Skutočnou killer featurou je pre mňa možnosť pracovať s predžúvaným dotazom. Môžem postupne aplikovať filtre:
if only_published:
qs = qs.filter(is_published=True)
if only_author:
qs = qs.filter(author=only_author)
...
Nad takto predžúvaným dotazom si môžem vytiahnuť štatistiky (ORM mi automaticky doplní všetky tie nechutnosti ako group by kde by som musel všetko vymenúvať znovu). Môžem nad predžúvaným querysetom vykonať limit a poslať do šablóny len časť ktorá ma zaujíma (limit, offset, alebo rownum between, proste čo daná db podporuje).
Existuji i jine metody, jak vyse uvedeny cil dosahnout (software je mozno provozovat s vice databazemi).
Aké? Nie že by to bolo pre mňa nejako dôležité, ale rád sa učím nové veci. Kvôli tomu vlastne blogujem na abclinuxu.cz, je tu skvelá komunita ktorá sa nehanbí kritizovať. V práci programujem sám, takže nejaký feedback zbieram už len kvôli tomu aby som sa dozvedel čo v mojom kóde / štýle programovania zlepšiť. Občas oponujem, ale neznamená to, že by som argument nebral do úvahy 
To, že nastavím poľu dĺžku 100 znakov a databáza mi negarantuje, že tam môžem uložiť 100 znakovZkusil jsem si to, funguje to správně:
DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`str1` varchar(10) COLLATE utf8mb4_czech_ci NOT NULL,
`str2` varchar(10) COLLATE utf8_czech_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_czech_ci;
INSERT INTO `a` (`str1`, `str2`) VALUES
('1234567890', '1234567890'),
('qwertyuiop', 'qwertyuiop'),
('+ěščřžýáíé', '+ěščřžýáíé'),
('+ěščřžýáíé+ěščřžýáíé', '+ěščřžýáíé+ěščřžýáíé');
SELECT * FROM `a`;
DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`str1` varchar(10) COLLATE utf8mb4_czech_ci NOT NULL,
`str2` varchar(10) COLLATE utf8_czech_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_czech_ci;
INSERT INTO `a` (`str1`, `str2`) VALUES
('1234567890', '1234567890'),
('qwertyuiop', 'qwertyuiop'),
('+ěščřžýáíé', '+ěščřžýáíé'),
('+ěščřžýáíé+ěščřžýáíé', '+ěščřžýáíé+ěščřžýáíé');
SELECT * FROM `a`;
V obou případech dostanu výsledek:
| str1 | str2 |
|---|---|
| 1234567890 | 1234567890 |
| qwertyuiop | qwertyuiop |
| +ěščřžýáíé | +ěščřžýáíé |
| +ěščřžýáíé | +ěščřžýáíé |
Máme staršiu verziu bez utf8mb4.
XML, JSON (áno nejaká paródia na JSON tam je, ale nedá sa napríklad indexovať), funkcionálne indexy, ACID, indexy nad viewmi, sekvencie, spatiálne vyhľadávanie (postgis, viem, že má aj mysql ale nekompletné), perl / python / javascript triggery, odolnosť voči poškodeniu dát, ...
MySQL sa síce tvári, že subselecty podporuje, ale v subselecte sa nedá použiť napr. limit.
CREATE TABLE `a` (
`str1` varchar(10) COLLATE utf8mb4_czech_ci NOT NULL,
`str2` varchar(10) COLLATE utf8_czech_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_czech_ci;
INSERT INTO `a` (`str1`, `str2`) VALUES
('1234567890', '1234567890'),
('qwertyuiop', 'qwertyuiop'),
('+ěščřžýáíé', '+ěščřžýáíé');
SELECT * FROM (SELECT * FROM `a` LIMIT 2) AS `b`;
str1 str2 1234567890 1234567890 qwertyuiop qwertyuiop
Máme staršiu verziu ktorá to považuje za chybu syntaxe.
Čo urobím s pokazenými DDL? MySQL musí kvôli tomu locknúť tabuľky (down time), nedá sa to uzatvoriť do transakcie (ak sa niečo škaredo pokazí nemôžem urobiť rollback). Nepodporuje funkcionálne indexy. Väčšinou chcem správanie unique indexov ako utf8_bin ale zoraďovanie podľa slovenčiny ... Poriadna podpora viewov s indexmi nad viewmi mi tiež chýba. Každá vec ktorú som chcel kedysi použiť bola akosi papierovo tam, ale bola tak neskutočne pokazená, že som sa na celú ich db vykašlal.