Пабудуйце ўласную базу даных фільмаў з API
amodb гэта незалежнае API, якое працуе па пратаколе TMDB v3. Фільмы, людзі, кампаніі, калекцыі, ключавыя словы і жанры маюць лікавыя id і спасылаюцца адно на адно, таму з яго можна запоўніць табліцы SQL і трымаць іх актуальнымі. Запаўняйце табліцы праз discover па старонках, абнаўляйце іх па ўзросце і супастаўляйце свае ідэнтыфікатары праз find. У amodb няма стужкі changes, таму абнаўленне гэта звычайнае паўторнае чытанне радкоў, якія вы захоўваеце.
Што вы атрымліваеце:
- Шэсць звязаных тыпаў сутнасцей са стабільнымі лікавымі id.
- Старонкі discover для першай загрузкі: да 20 вынікаў на старонку, 500 старонак на запыт.
- Вокны дат выхаду ў discover, каб дзяліць першую загрузку і атрымліваць новыя рэлізы.
- Пошук па вонкавых id для
imdb_id,tvdb_id,wikidata_idіkinopoisk_id.
Якія даныя вы атрымліваеце
Гэта мадэль даных. Кожны радок гэта адна табліца ў рэляцыйнай копіі.
| Сутнасць | Чытаць праз | Ключ | Звязана з |
|---|---|---|---|
| Фільм | GET / | id, imdb_id | genres[].id, production_, belongs_ |
| Персона | GET / | id, imdb_id | Фільмамі праз / |
| Кампанія | GET / | id | Фільмамі праз with_companies у discover. parent_company заўсёды null, а description пусты |
| Калекцыя | GET / | id | parts[], спіс фільмаў |
| Ключавое слова | GET / | id | Фільмамі праз / або with_keywords |
| Жанр | GET / | id | genres[].id у фільмах |
Сувязі «многія да многіх» патрабуюць злучальных табліц: movie_genre, movie_company, movie_keyword і movie_credit. Выкарыстоўвайце credit_id са старонкі удзельнікі як ключ апошняй. Спісы палёў ёсць на старонках фільмы, персоны і калекцыі.
Пачніце за 3 крокі
- Параўнайце тры частаты запытаў на старонцы цэны. Большая частата скарачае першую загрузку, больш нічога не мяняецца.
- Стварыце ключ у асабістым кабінеце і трымайце яго ў зменнай асяроддзя.
- Выклічце
/3/discover/movieдля аднадзённага акна дат выхаду, потым атрымайце кожны id са спісу.
Прыклад запыту
Скрыпт на PHP пералічвае фільмы, што выйшлі ўчора і сёння, праз discover і дадае або абнаўляе кожны запіс у табліцы SQLite. Ён спіць 3 секунды паміж чытаннямі дэталяў, каб заставацца ніжэй за 20 запытаў у хвіліну, паўтарае 429 пасля Retry-After і выдаляе радкі, чый id цяпер вяртае 404.
curl -s "https://api.amodb.dev/3/discover/movie?primary_release_date.gte=2026-10-17&primary_release_date.lte=2026-10-18&sort_by=primary_release_date.asc&page=1" \
-H "Authorization: Bearer $AMODB_KEY"<?php
const BASE = 'https://api.amodb.dev/3';
function amodb(string $path, array $query = []): ?array
{
$url = BASE . $path . '?' . http_build_query($query);
for ($attempt = 0; $attempt < 3; $attempt++) {
$retryAfter = 1;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
CURLOPT_HEADERFUNCTION => function ($handle, $line) use (&$retryAfter) {
if (stripos($line, 'Retry-After:') === 0) {
$retryAfter = max(1, (int) trim(substr($line, 12)));
}
return strlen($line);
},
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 429) {
sleep($retryAfter);
continue;
}
if ($status === 404) {
return null;
}
if ($status !== 200) {
throw new RuntimeException("amodb returned $status for $path");
}
return json_decode($body, true);
}
throw new RuntimeException("Still rate limited on $path");
}
$db = new PDO('sqlite:movies.sqlite');
$db->exec('CREATE TABLE IF NOT EXISTS movie (id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, release_date TEXT, raw TEXT)');
$save = $db->prepare('INSERT OR REPLACE INTO movie (id, imdb_id, title, release_date, raw) VALUES (?, ?, ?, ?, ?)');
$drop = $db->prepare('DELETE FROM movie WHERE id = ?');
$from = date('Y-m-d', strtotime('-1 day'));
$to = date('Y-m-d');
$page = 1;
do {
$list = amodb('/discover/movie', [
'primary_release_date.gte' => $from,
'primary_release_date.lte' => $to,
'sort_by' => 'primary_release_date.asc',
'page' => $page,
]);
foreach ($list['results'] as $row) {
$movie = amodb('/movie/' . $row['id'], ['language' => 'en-US']);
if ($movie === null) {
$drop->execute([$row['id']]);
continue;
}
$save->execute([$movie['id'], $movie['imdb_id'] ?? null, $movie['title'], $movie['release_date'] ?? null, json_encode($movie)]);
sleep(3);
}
$page++;
} while ($page <= min($list['total_pages'], 500));Discover вяртае радкі спісу, а не поўныя запісы. Гэта 2 з 20 вынікаў на старонцы 1. Астатнія палі чытайце з /3/movie/{id}.
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/siepLRGVjM8yLKppApkD3uSh8Y0.jpg",
"genre_ids": [
35
],
"id": 1800227,
"original_language": "en",
"original_title": "Sly's Pack",
"overview": "Nesmith, Gary, & Tony are smoking weed on the roof of a parking garage, but a...",
"popularity": 0.0071,
"poster_path": "/3HpIWZUI7jmpKZkfZNdchS2WsvN.jpg",
"release_date": "2026-10-17",
"title": "Sly's Pack",
"video": false,
"vote_average": 0,
"vote_count": 0
},
{
"adult": false,
"backdrop_path": null,
"genre_ids": [
99
],
"id": 1800168,
"original_language": "en",
"original_title": "The Good Life",
"overview": "The Good LIfe is based on the best-selling book by Drs. Robert Waldinger and...",
"popularity": 0.0143,
"poster_path": null,
"release_date": "2026-10-17",
"title": "The Good Life",
"video": false,
"vote_average": 0,
"vote_count": 0
}
],
"total_pages": 15,
"total_results": 299
}Запаўненне і абнаўленне табліц
| Задача | Выклік | Абмежаванні |
|---|---|---|
| Першая загрузка | GET /3/discover/movie з sort_by і акном дат | page ад 1 да 500, да 20 вынікаў на старонку, то бок 10 000 на запыт. Каб выйсці за гэта, дзяліце па primary_ і .lte. |
| Новыя рэлізы | GET /3/discover/movie з primary_, роўным часу апошняга запуску, і GET /3/movie/upcoming | Кэшуецца 30 хвілін. |
| Абнаўленне радкоў | GET / для радкоў старэйшых за 6 гадзін | Стужкі changes няма. Абнаўляйце назвы, якія адкрываюць карыстальнікі, а астатнія радзей. |
| Злучэнне ўласных id | GET / | Адзін id на выклік, крыніца вызначаецца праз external_source. |
| Лянівае запаўненне | GET /, калі карыстальнік адкрывае назву | Захоўвайце адказ з часавой пазнакай. |
Акно старонак гэта галоўнае рашэнне ў праектаванні. Калі total_pages у адказе вышэй за 500, акно змяшчае больш за 10 000 радкоў, таму дзеліце яго напалам, пакуль не памесціцца. Для апошняга года патрэбны месяцы, а адзін дзень рэлізаў гэта некалькі соцень назваў. Захоўвайце скончаны кавалак, каб запуск, што збоіў, мог працягнуцца. Правілы супастаўлення для злучэння гл. на старонцы пошук па вонкавым ідэнтыфікатары.
Ацэнка аб’ёму сінхранізацыі
Кожны абноўлены радок каштуе адно чытанне дэталяў. План на 20 запытаў у хвіліну дае 1200 выклікаў у гадзіну, 40 дае 2400, а 120 дае 7200. Старонка discover пералічвае 20 id за адзін выклік. Запускайце абнаўленне ў гадзіны меншай нагрузкі, калі ваша праграма дзеліць ключ, бо ліміт дзейнічае на ключ, а не на скрыпт. Загалоўкі, што паказваюць, колькі засталося ў акне, гл. на старонцы ліміты запытаў.
Кэшаванне ў два пласты
| Пласт | Што трымае | TTL |
|---|---|---|
| Edge-кэш | Дэталі і ўдзельнікі | 6 гадзін |
| Edge-кэш | Спісы discover, трэндаў і папулярных | 30 хвілін |
| Edge-кэш | Пошук | 10 хвілін |
| Edge-кэш | Канфігурацыя | 24 гадзіны |
| Edge-кэш | Выявы | 30 дзён |
| Вашы табліцы | Радкі, якія вы захоўваеце | Пакуль правіла ўзросту не скажа паўтарыць запыт, але не раней за 6 гадзін |
Edge-кэш агульны для ключоў, але ліміт запытаў правяраецца да яго, таму трапленне ў кэш усё роўна расходуе адзін запыт з вашай хвіліны. Паўторнае чытанне радка часцей чым раз у 6 гадзін вяртае тую ж копію і марнуе квоту. Хай правіла ўзросту вырашае, калі абнаўляць.
Параўнанне
| Магчымасць | Уласны скрэйпінг старонак | Статычныя файлы набораў даных | amodb |
|---|---|---|---|
| Свежасць | Настолькі свежа, як апошні абыход | Настолькі свежа, як апошні апублікаваны файл | Дэталі кэшуюцца 6 гадзін, абнаўляйце па ўзросце |
| Паэтапныя абнаўленні | Паўторны абыход і параўнанне | Спампаваць новы файл | Discover з акном даты выхаду, без стужкі changes |
| Id паміж сутнасцямі | URL старонак | Вызначае выдавец | Лікавыя id, imdb_id і /3/find |
| Што вы запускаеце | Краўлеры і сховішча | Сховішча і задача імпарту | Сховішча і скрыпт сінхранізацыі |
| Ліміт запытаў | Вызначаюць сайты, якія вы абыходзіце | Не ўжываецца | 20, 40 або 120 запытаў у хвіліну, на ключ |
| Мовы на запіс | Тое, што прапануе кожная старонка | Залежыць ад файлаў | 14, выбіраюцца праз language |
Цэны
Першая загрузка самая дарагая, і яна абмежавана вашымі запытамі ў хвіліну. Абярыце 20, 40 або 120 у хвіліну на старонцы цэны. Плаціце за 1, 3, 6, 12 або 24 месяцы са зніжкай 0, 10, 20, 30 або 40 працэнтаў. Нічога не прадаўжаецца аўтаматычна, бясплатнага тарыфа няма, і кожны план чытае тыя ж даныя.