{"id":372050,"date":"2024-05-21T05:03:05","date_gmt":"2024-05-21T05:03:05","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=372050"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=372050","title":{"rendered":"<span>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f Grist \u0438 Metabase<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0415\u0436\u043a\u043e\u0432, \u044f Backend-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 <a href=\"https:\/\/clck.ru\/39iHe4\">AGIMA<\/a>. \u0417\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0410 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u2014 \u043d\u0430\u0448\u0435\u0439 DWH-\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439. \u041c\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0435\u0435 \u0438\u0437 Open-source \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0445\u0438\u0442\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438 \u0438 \u043a\u0430\u043a \u0432\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u043c\u0435\u0441\u0442\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/ba0\/531\/759\/ba0531759d24e41b640f170cca239697.jpg\" width=\"1200\" height=\"600\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba0\/531\/759\/ba0531759d24e41b640f170cca239697.jpg\" data-blurred=\"true\"\/><\/figure>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 DWH<\/h2>\n<p>DWH (Data Warehouse) \u2014 \u044d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0447\u0435\u0441\u043a\u043e\u0439 \u043e\u0442\u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 DWH \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044f\u043c \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/agima\/articles\/803535\/\"><u>>> \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043d\u0430\u0448 \u043d\u044c\u044e\u0431\u0438\u0437 \u0412\u0438\u0442\u0430\u043b\u0438\u0439 \u0414\u043e\u0449\u0435\u043d\u043a\u043e.<\/u><\/a><\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0431\u0430\u0437\u0435 \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0440\u0430\u0441\u0445\u043e\u0434\u0430\u0445 \u0438 \u0434\u043e\u0445\u043e\u0434\u0430\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0443 AGIMA. \u042d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0438 \u0438\u0445 \u043d\u0435\u043c\u043d\u043e\u0433\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0447\u0438\u0441\u0442\u043a\u0438 \u0438\u043b\u0438 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b DWH.<\/p>\n<h2>Grist<\/h2>\n<p>Grist \u2014 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430. \u041f\u043e \u0441\u0443\u0442\u0438, \u044d\u0442\u043e \u0433\u0438\u0431\u0440\u0438\u0434 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u2014 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435, \u043a\u0430\u043a Google Sheet \u0438\u043b\u0438 Excel. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<ol>\n<li>\n<p>\u0421\u0442\u043e\u043b\u0431\u0446\u044b \u0432 Grist \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u0411\u0414: \u043e\u043d\u0438 \u0438\u043c\u0435\u044e\u0442 \u0438\u043c\u0435\u043d\u0430 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043e\u0434\u0438\u043d \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u043f\u043e \u0444\u043e\u0440\u043c\u0443\u043b\u0435 \u2014 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435: \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u044f\u0447\u0435\u0435\u043a, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412 Grist \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 Python, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 Excel. \u0412 \u043e\u0441\u043d\u043e\u0432\u0435 Grist SQLite. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u044e\u0431\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0447\u0438\u0442\u0430\u0442\u044c SQLite, \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u0442 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 Grist.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0434\u0435\u0441\u044c \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0445\u043e\u0441\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0423 Grist \u0445\u043e\u0440\u043e\u0448\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 <a href=\"https:\/\/support.getgrist.com\/api\/\"><u>API<\/u><\/a>. \u0410 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Excel \u0438 Google-\u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 Grist \u2014 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. Grist \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u043c\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u044f\u043c\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c, \u0441\u0442\u043e\u043b\u0431\u0446\u0430\u043c \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u044f\u0447\u0435\u0435\u043a \u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c SSO-\u043b\u043e\u0433\u0438\u043d (\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/goauthentik.io\/\"><u>authentik<\/u><\/a>) \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/gristlabs\/grist-omnibus\"><u>\u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/u><\/a>. <a href=\"https:\/\/support.getgrist.com\/install\/saml\/#example-authentik\"><u>\u041c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 Grist \u0432 authentik<\/u><\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c Grist, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Docker:<\/p>\n<pre><code class=\"bash\">docker pull gristlabs\/grist docker run -p 8484:8484 -v $PWD\/persist:\/persist -it gristlabs\/grist<\/code><\/pre>\n<p>Grist \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 http:\/\/localhost:8484. \u0412\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#8212; v<code>$PWD\/persist:\/persist.<\/code> <\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 Grist<\/h3>\n<p>\u0414\u043b\u044f \u0443\u0447\u0435\u0442\u0430 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 \u0438 \u0434\u043e\u0445\u043e\u0434\u043e\u0432 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u043b \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043e\u043a. \u0423 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043f\u043e\u0438\u0441\u043a\u0443:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u0431\u043b\u0438\u0446, \u043a\u043e\u043b\u043e\u043d\u043e\u043a, \u0441\u0442\u0440\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u0431\u044b\u0441\u0442\u0440\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>Grist \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u043d \u0438\u043c\u0435\u0435\u0442 \u0433\u0438\u0431\u043a\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0440\u0430\u0441\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438, \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u044f\u0447\u0435\u0439\u043a\u0438, \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0443\u043b\u044b, \u0438\u043c\u0435\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b, \u0438\u043c\u0435\u0435\u0442 \u0433\u0438\u0431\u043a\u0438\u0439 API, \u0430 \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/github.com\/gristlabs\/py_grist_api\"><u>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043d\u0430 Python<\/u><\/a>.<\/p>\n<h3>\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Grist<\/h3>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0434\u0443\u043c\u0430\u043d\u044b.<\/p>\n<p>\u0412 Grist \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u043b\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438, \u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438\u00bb.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d2d\/061\/4de\/d2d0614dea1006b40f99cbd431b9c19c.png\" alt=\"\" title=\"\" width=\"816\" height=\"320\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d2d\/061\/4de\/d2d0614dea1006b40f99cbd431b9c19c.png\"\/><\/figure>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u043a\u043d\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0438\u0437 \u0440\u043e\u043b\u0435\u0439: \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446, \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f78\/92b\/ac5\/f7892bac54317a578a2705f331efc07d.png\" alt=\"\" title=\"\" width=\"619\" height=\"562\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f78\/92b\/ac5\/f7892bac54317a578a2705f331efc07d.png\"\/><\/figure>\n<p>\u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/99b\/d57\/38a\/99bd5738a73ab544d47ac60c2aab6f9b.png\" width=\"1037\" height=\"197\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/99b\/d57\/38a\/99bd5738a73ab544d47ac60c2aab6f9b.png\"\/><\/figure>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c, \u0430 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0438\u0434\u0435\u0442\u044c \u0432\u0441\u0435. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0442\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u044d\u0442\u043e\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/210\/815\/b45\/210815b450e4f9de59f47c90671d8c85.png\" width=\"901\" height=\"182\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/210\/815\/b45\/210815b450e4f9de59f47c90671d8c85.png\"\/><\/figure>\n<p>\u041d\u0438\u0436\u0435 \u0432 Grist \u0435\u0441\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\u00bb. \u041d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0433\u0438\u0431\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0430\u0431\u043b\u0438\u0446, \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u0438 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b6c\/c65\/b86\/b6cc65b86afadba7767d3e4ad3d742d6.png\" alt=\"\" title=\"\" width=\"1372\" height=\"885\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b6c\/c65\/b86\/b6cc65b86afadba7767d3e4ad3d742d6.png\"\/><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0432\u0438\u0434\u0435\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u043e\u043a\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Team, \u043d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u00bb, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u044b. \u0417\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b\u00bb \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432 \u043c\u0435\u043d\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/966\/1e7\/272\/9661e7272551ca0bc192c46e653ff233.png\" width=\"825\" height=\"853\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/966\/1e7\/272\/9661e7272551ca0bc192c46e653ff233.png\"\/><\/figure>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u0423\u0441\u043b\u043e\u0432\u0438\u0435\u00bb \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u043b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f Read, Update, Create, Delete:<\/p>\n<pre><code class=\"python\">user.Team.Role == \"\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\" and user.Access != OWNER and user.Name == rec.responsible and user.Name == newRec.responsible<\/code><\/pre>\n<p><strong>user.Team.Role<\/strong> \u2014 \u044d\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0443 \u043c\u044b \u043f\u043e \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u0443\u044e \u043d\u0430\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0443 Role \u0432 \u0441\u0442\u0440\u043e\u043a\u0435, \u0433\u0434\u0435 email == \u201c<a href=\"mailto:a.ezhkov@agima.ru\"><u>a.ezhkov@agima.ru<\/u><\/a>\u201d.  <\/p>\n<p><strong>user.Access<\/strong> \u2014 \u044d\u0442\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0437\u0430\u0434\u0430\u043b\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u043b\u0438 \u0435\u0433\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d \u0440\u0430\u0432\u0435\u043d EDITOR, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u00ab\u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0415\u0436\u043a\u043e\u0432\u00bb \u043c\u044b \u0434\u0430\u043b\u0438 \u0440\u043e\u043b\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430.<\/p>\n<p><strong>user.Name<\/strong> \u2014 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p><strong>rec<\/strong> \u2014 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0432\u044b\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p><strong>rec.responsible<\/strong> \u2014 \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb. \u0423\u0441\u043b\u043e\u0432\u0438\u0435 <strong>user.Name == rec.responsible<\/strong> \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0443 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p><strong>newRec<\/strong> \u2014 \u044d\u0442\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442 <strong>rec<\/strong>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c, \u043f\u0440\u0438\u0447\u0435\u043c <strong>rec<\/strong> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0430 <strong>newRec<\/strong> \u2014 \u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043b \u0432\u0441\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f CRUD:<\/p>\n<pre><code class=\"python\">user.Team.Role == \"\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\" and user.Access != OWNER and user.Name != rec.responsible<\/code><\/pre>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u00bb \u044f \u0443\u0431\u0440\u0430\u043b \u0433\u0430\u043b\u043e\u0447\u043a\u0443 \u00ab\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443\u00bb \u0438 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043c\u043e\u0433\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u044b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0440\u043e\u043b\u044c\u044e \u00ab\u0411\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u00bb.<\/p>\n<p>\u041d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a\u00bb \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u0432\u0438\u0434\u044f\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a75\/982\/813\/a75982813b63b074a50d6beac38104e6.png\" width=\"850\" height=\"655\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a75\/982\/813\/a75982813b63b074a50d6beac38104e6.png\"\/><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u043c\u043e\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0438, \u0433\u0434\u0435 \u044f \u0432 \u0440\u043e\u043b\u0438 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e\u00bb.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/038\/9a3\/2d1\/0389a32d1837d276ed168c7c0bc6016b.png\" width=\"1047\" height=\"247\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/038\/9a3\/2d1\/0389a32d1837d276ed168c7c0bc6016b.png\"\/><\/figure>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u043e\u0441\u044c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0442\u043e\u043b\u0431\u0446\u0430 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0417\u0430\u0434\u0430\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443\u043b\u0443\u00bb. \u0412 \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0435 \u043f\u0438\u0448\u0435\u043c \u0444\u043e\u0440\u043c\u0443\u043b\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0433\u0430\u043b\u043e\u0447\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0444\u043e\u0440\u043c\u0443\u043b\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u043b\u0430\u0441\u044c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438:<\/p>\n<pre><code class=\"python\">user.Name if Table4.lookupOne(Email=user.Email).Role == \"\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\" else value<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4f9\/b7e\/f4b\/4f9b7ef4b8921ce0e4f7b316e9ebb994.png\" width=\"307\" height=\"489\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4f9\/b7e\/f4b\/4f9b7ef4b8921ce0e4f7b316e9ebb994.png\"\/><\/figure>\n<p>\u041c\u0435\u0442\u043e\u0434 Table4.lookupOne \u0438\u0449\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb \u043f\u043e \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u0435 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 Role. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440, \u0442\u043e \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0433\u043e \u0438\u043c\u044f, \u0430 \u0435\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0432\u043e\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u00ab\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438\u00bb \u0438 \u043d\u0430\u0436\u043c\u0435\u043c Enter. \u0412 \u043f\u043e\u043b\u0435 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043c\u043e\u0435 \u0438\u043c\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6ce\/35a\/2f8\/6ce35a2f81d2fbf2236f6ef8622b6f5b.png\" width=\"818\" height=\"174\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6ce\/35a\/2f8\/6ce35a2f81d2fbf2236f6ef8622b6f5b.png\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb \u0432\u0441\u0435\u043c, \u043a\u0440\u043e\u043c\u0435 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0438 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\u00bb \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0430 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0441\u0451 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c:<\/p>\n<pre><code class=\"python\">user.Access == OWNER or user.Team.Role in ['\u0411\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440']<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8eb\/b0e\/bc6\/8ebb0ebc6b46e3c6115470118e11bc84.png\" width=\"783\" height=\"153\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8eb\/b0e\/bc6\/8ebb0ebc6b46e3c6115470118e11bc84.png\"\/><\/figure>\n<p>\u0417\u0430\u0439\u0434\u0435\u043c \u043f\u043e\u0434 \u043c\u043e\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0438 \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u043f\u0430\u043b\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/169\/cb9\/63b\/169cb963b5b99bc89db7e101fc99a1f5.png\" width=\"1210\" height=\"225\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/169\/cb9\/63b\/169cb963b5b99bc89db7e101fc99a1f5.png\"\/><\/figure>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446 \u0443 \u043d\u0430\u0441 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c, \u0442\u043e \u0432 \u043f\u043e\u043b\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043d\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0430 \u0435\u0435 ID. \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0442\u0430\u0431\u043b\u0438\u0446 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\u00bb.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dac\/b87\/c6b\/dacb87c6b772c10960455242e6a437d6.png\" width=\"1056\" height=\"810\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dac\/b87\/c6b\/dacb87c6b772c10960455242e6a437d6.png\"\/><\/figure>\n<h3>Grist API \u0438 Airflow<\/h3>\n<p>Apache Airflow \u2014 \u044d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0447\u0438\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438 (Workflow Management Platform), \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f Airbnb. \u041e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 (Workflows) \u0432 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u042d\u0442\u043e \u0443\u0436\u0435 \u043e\u0442\u0440\u0430\u0441\u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0434\u043b\u044f \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.\u00a0<\/p>\n<p>Airflow \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0440\u044f\u0434\u043e\u043c \u0441 Grist \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Docker. \u0423 Grist \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/gristlabs\/py_grist_api\"><u>\u043a\u043b\u0438\u0435\u043d\u0442<\/u><\/a>, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Python, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u0434\u0430\u0433\u0430\u0445 Airflow, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435.\u00a0<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 py_grist_api, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0434\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u00bb, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f GRIST_API_KEY \u0441 \u043a\u043b\u044e\u0447\u043e\u043c API. \u0422\u0430\u043a\u0436\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0432 \u0444\u0430\u0439\u043b ~\/.grist-api-key. \u041a\u043b\u044e\u0447 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fe8\/bed\/685\/fe8bed685b5effba5254d89d4c896758.png\" width=\"638\" height=\"670\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fe8\/bed\/685\/fe8bed685b5effba5254d89d4c896758.png\"\/><\/figure>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0432\u0438\u0434\u0430 \u0434\u0430\u0433\u043e\u0432 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437 Grist. \u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0438\u0434 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0438 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0438\u0434 \u0434\u0430\u0433\u043e\u0432 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0440\u0430\u0437 \u0432 \u0441\u0443\u0442\u043a\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a \u0441\u0442\u0430\u0440\u043e\u0439, \u043d\u043e \u0441 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0439 \u0434\u0430\u0442\u043e\u0439. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u044f, \u043a\u0430\u043a\u043e\u0439 \u0431\u044b\u043b\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0432 Grist \u0440\u0430\u043d\u044c\u0448\u0435 \u0437\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0434\u0435\u043d\u044c. \u041c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0445 DIM-\u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u0438\u043b\u0438 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430\u043c\u0438. \u0412\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0432 PostgreSQL. <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u0430\u0433\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430: <strong>schedule_interval<\/strong> \u0438 <strong>start_date<\/strong>, \u0433\u0434\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u043e Cron-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 Datetime-\u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p>\u041a\u043e\u0434 \u0432 \u0434\u0430\u0433\u0430\u0445 Airflow \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438\u0437 Grist \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441:<\/p>\n<pre><code class=\"python\">from airflow.models import Variable from grist_api import GristDocAPI   @dag(        dag_id=dag_id,        params=params,        schedule_interval='0 * * * *',        start_date=pendulum.datetime(2022, 6, 30, 0, 0, 0, tz='UTC'),        catchup=False,        render_template_as_native_obj=True,        tags=tags,    )    def grist_T_pg():        \"\"\"        ### GAD ETL: \u0412\u0441\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b        \u0412\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 Gtist \u0432 PostgreSQL        \"\"\"         @task()        def extract(**context):            \"\"\"            #### Extract task            \u041f\u043e\u043b\u0443\u0447\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 Grist \u043f\u043e API            \"\"\"            SERVER = Variable.get('API_URL_grist')            DOC_ID = Variable.get('GRIST_DOC_ID')             api = GristDocAPI(                DOC_ID,                server=SERVER            )             data = api.call(f\"tables\/{context['params'].get('grist')}\/data\")             return data<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432 context[&#8216;params&#8217;].get(&#8216;grist&#8217;) \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p>\u041a\u043e\u0434 \u0432 \u0434\u0430\u0433\u0430\u0445 Airflow \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437 \u0432 \u0441\u0443\u0442\u043a\u0438:<\/p>\n<pre><code class=\"python\">@dag(        dag_id=dag_id,        params=params,        schedule_interval='30 1 * * *',        start_date=pendulum.datetime(2022, 6, 30, 1, 0, 0, tz='UTC'),        catchup=False,        render_template_as_native_obj=True,        tags=tags,    )    def dimension_tables():        \"\"\"        ### GAD Dimension Tables        \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 dim-\u0442\u0430\u0431\u043b\u0438\u0446        \"\"\"          @task()        def read(**context):            \"\"\"            #### Read task            \u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b            \"\"\"              hook = PostgresHook('dwh')            engine = hook.get_sqlalchemy_engine()            conn = engine.connect()              sql = f\"SELECT * FROM {context['params'].get('dwh')}\"              try:                df = pd.read_sql(                    sql,                    conn                )            finally:                conn.close()              return df.to_dict()          @task()        def copy(data: dict, **context):            \"\"\"            #### Copy task            \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043f\u0438\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b            \"\"\"              updated_today = was_update_today(table=f\"{context['params'].get('dwh')}__dim\")            if updated_today: return            hook = PostgresHook('dwh')            engine = hook.get_sqlalchemy_engine()            conn = engine.connect()              try:                df = pd.DataFrame.from_dict(                    data=data                ) # \u0414\u0430\u0442\u0430 \u0438 \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b                df['ds'] = pd.to_datetime('today').normalize()                  df.to_sql(                    f\"{context['params'].get('dwh')}__dim\",                    conn,                    index=False,                    if_exists='append'                )            finally:                conn.close()          data = read()        copy(data)<\/code><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e\u00a0 \u044d\u0442\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u0432 \u0434\u043e\u0445\u043e\u0434\u0430\u0445 \u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u0430\u0445 \u0441 \u043f\u0440\u043e\u0448\u043b\u044b\u043c\u0438 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0435\u043d\u0434\u044b \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0430\u0445 \u0432 Metabase. \u041a\u0430\u043a \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043e\u0442\u0447\u0435\u0442 \u0432 Metabase, \u043d\u044c\u044e\u0431\u0438\u0437-\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440 AGIMA \u0412\u0438\u0442\u0430\u043b\u0438\u0439 \u0414\u043e\u0449\u0435\u043d\u043a\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <a href=\"https:\/\/habr.com\/ru\/companies\/agima\/articles\/803535\/\"><u>\u00ab\u0421\u043e\u0437\u0434\u0430\u0435\u043c SQL-\u043e\u0442\u0447\u0435\u0442 \u0432 Metabase, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u043a\u0435\u00bb.\u00a0<\/u><\/a><\/p>\n<h3>Metabase \u0438 psql-http<\/h3>\n<p>Metabase \u2014 \u044d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043e\u0442\u0447\u0435\u0442\u044b. \u042d\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0445 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c\u0438 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u0439.<\/p>\n<p>Metabase \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041e\u043d \u0438\u043c\u0435\u0435\u0442 \u043d\u0438\u0437\u043a\u0438\u0439 \u0431\u0430\u0440\u044c\u0435\u0440 \u0432\u0445\u043e\u0434\u0430, \u0445\u043e\u0440\u043e\u0448\u0443\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c SQL \u043b\u0438\u0431\u043e \u0447\u0435\u0440\u0435\u0437 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. <a href=\"https:\/\/www.metabase.com\/learn\/permissions\/ldap-auth-access-control\"><u>\u0422\u0430\u043a\u0436\u0435 Metabase \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 LDAP \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/u><\/a><u><br \/><\/u><br \/>\u0414\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Metabase \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Docker:<\/p>\n<pre><code class=\"bash\">docker pull metabase\/metabase:latest docker run -d -p 3000:3000 --name metabase metabase\/metabase<\/code><\/pre>\n<p>\u041d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439, \u043e \u0442\u043e\u043c, <a href=\"https:\/\/habr.com\/ru\/companies\/agima\/articles\/679136\/\"><u>\u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Metabase<\/u><\/a>, \u043a\u0430\u043a \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u043c \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u044b, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0440\u043e\u0447\u0435\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043b\u0443\u0447\u0448\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u0433\u043e\u0432 \u0432 Airflow \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0430 Metabase, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>\u041a\u0430\u043a-\u0442\u043e \u0440\u0430\u0437 \u043f\u0440\u0438\u0448\u0435\u043b \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440 \u0438 \u0441\u043a\u0430\u0437\u0430\u043b: \u00ab\u041c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 Grist, \u0430 \u043f\u043e\u0442\u043e\u043c \u0436\u0434\u0435\u043c \u0447\u0430\u0441, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0430\u0445 \u0432 Metabase. \u041d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u044b \u0441\u0440\u0430\u0437\u0443, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\u00bb.<\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c API Airflow \u043f\u0440\u044f\u043c\u043e \u0438\u0437 Metabase \u0438 \u043e\u0444\u043e\u0440\u043c\u0438\u0442\u044c \u044d\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0427\u0442\u043e\u0431\u044b \u0432 Airflow \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u0430\u0433, \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 <a href=\"https:\/\/airflow.apache.org\/docs\/apache-airflow\/stable\/stable-rest-api-ref.html#operation\/get_dag_runs\"><u>\u044d\u0442\u043e\u0442<\/u><\/a> \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442:\u00a0<\/p>\n<p><a href=\"https:\/\/airflow.apache.org\/api\/v1\/dags\/%7Bdag_id%7D\/dagRuns\"><u>\/api\/v1\/dags\/{dag_id}\/dagRuns<\/u><\/a>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 Metabase. \u041f\u043e\u0441\u043b\u0435 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0444\u0438\u0447\u0430 <a href=\"https:\/\/www.metabase.com\/docs\/latest\/actions\/start\"><u>Actions<\/u><\/a>. <strong>Actions<\/strong> \u2014 \u044d\u0442\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 Metabase, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443. \u041e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 SQL, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0432\u0430\u0448\u0443 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. Actions \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u0442\u044c \u043a \u043a\u043d\u043e\u043f\u043a\u0430\u043c \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0430\u0445 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432. \u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e Actions \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c CRUD-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0435.<\/p>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 Actions \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f PostgreSQL \u0438 MySQL. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043f\u043e Actions \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/www.metabase.com\/docs\/latest\/actions\/introduction\"><u>\u0437\u0434\u0435\u0441\u044c<\/u><\/a>.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433 \u043c\u043d\u0435 \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u044d\u0442\u043e <a href=\"https:\/\/github.com\/pramsey\/pgsql-http\"><u>psql-http<\/u><\/a> \u2014 HTTP-\u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f PostgreSQL, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"bash\">wget -O pgsqlhttp.tar.gz \"https:\/\/github.com\/pramsey\/pgsql-http\/archive\/refs\/tags\/${PGSQL_HTTP_VERSION}.tar.gz\"  mkdir -p \/usr\/src\/pgsqlhttp tar --extract --file pgsqlhttp.tar.gz  --directory \/usr\/src\/pgsqlhttp --strip-components 1  rm pgsqlhttp.tar.gz  cd \/usr\/src\/pgsqlhttp  make  make install <\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"pgsql\">CREATE EXTENSION IF NOT EXISTS \"http\";<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 psql-http:<\/p>\n<pre><code class=\"sql\">SELECT status, content_type FROM http_get('http:\/\/httpbin.org\/');<\/code><\/pre>\n<p>\u041e\u0442\u0432\u0435\u0442:\u00a0<\/p>\n<pre><code class=\"sql\">status |       content_type --------+--------------------------     200 | text\/html; charset=utf-8 (1 row)<\/code><\/pre>\n<p>\u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e psql-http, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c API Airflow \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0447\u0435\u0440\u0435\u0437 Actions \u0432 Metabase. \u0412\u043e\u0442 \u0438 \u0432\u0441\u0451.<\/p>\n<h3>\u041a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0435<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0435, \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u00ab\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u041c\u043e\u0434\u0435\u043b\u044c\u044e\u00bb \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 Metabase.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6d3\/bd1\/77b\/6d3bd177b8510b08bda03c3acdfcbf06.png\" width=\"1227\" height=\"778\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6d3\/bd1\/77b\/6d3bd177b8510b08bda03c3acdfcbf06.png\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u00bb, \u0437\u0430\u0442\u0435\u043c \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u00bb.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0a9\/5bc\/f62\/0a95bcf62caaba10b3fb400ebffa315d.png\" width=\"1600\" height=\"461\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0a9\/5bc\/f62\/0a95bcf62caaba10b3fb400ebffa315d.png\"\/><\/figure>\n<p>\u0412\u0432\u0435\u0441\u0442\u0438 \u0442\u0435\u043a\u0441\u0442 \u043a\u043d\u043e\u043f\u043a\u0438 \u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u00bb. \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u00bb. \u041e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u043a\u043d\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0438\u0448\u0435\u0442\u0441\u044f SQL-\u0437\u0430\u043f\u0440\u043e\u0441. \u042d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443.   <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9d1\/5ae\/e95\/9d15aee957e5029058ffee188d8f10ff.png\" width=\"888\" height=\"809\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9d1\/5ae\/e95\/9d15aee957e5029058ffee188d8f10ff.png\"\/><\/figure>\n<p>\u041d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u0432\u044b\u0448\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e Actions \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e CREATE-, INSERT- \u0438 DELETE-\u0437\u0430\u043f\u0440\u043e\u0441\u044b. \u0410 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 SELECT. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e CTE \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e \u0435\u0433\u043e \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 UPDATE \u2026 WHERE false = true. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0443 \u043c\u0435\u043d\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f start_dags, \u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 Table1 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0414\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 start_dags, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0433\u0447\u0435 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0432\u044b\u0437\u0432\u0430\u0442\u044c API Airflow \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e psql-http.<\/p>\n<pre><code class=\"pgsql\">CREATE OR REPLACE FUNCTION start_dags(dags text[]) RETURNS boolean LANGUAGE PLPGSQL AS $$ DECLARE  current_dag text;  login text := 'login';   pass text := 'password'; result http_response array; BEGIN  FOREACH current_dag IN ARRAY dags LOOP    result := array_append(result, start_dag_run(login, pass, current_dag));  END LOOP; return true; END; $$;<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f start_dag_run:  <\/p>\n<pre><code class=\"pgsql\">CREATE OR REPLACE FUNCTION start_dag_run(login text, pass text, dag_id text) RETURNS http_response LANGUAGE PLPGSQL AS $$ declare result http_response; url text; headers http_header array; logpass text; begin url := concat('http:\/\/airflow-webserver\/api\/v1\/dags\/', dag_id, '\/dagRuns'); logpass := concat(login, ':', pass); headers := array[http_header('Authorization', concat('Basic ', encode(logpass::bytea, 'base64')))]; select *    into result from http(('POST', url, headers, 'application\/json', '{}')::http_request); return result; end; $$;<\/code><\/pre>\n<h3>\u041f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u0438 \u0434\u0435\u043c\u043e-\u0432\u0435\u0440\u0441\u0438\u044f<\/h3>\n<p><a href=\"https:\/\/github.com\/ezhkovskii\/DWH\"><u>\u0427\u0442\u043e\u0431\u044b \u0432\u0430\u043c \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0436\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438\u0437 Docker-compose \u0444\u0430\u0439\u043b\u043e\u0432<\/u><\/a>. \u041f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435\u0441\u044c!<\/p>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a Grist \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0438 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0435\u0433\u043e \u0440\u0443\u043a\u0430\u043c\u0438, <a href=\"https:\/\/demo-dwh-agima.ru\/\"><u>\u0432\u043e\u0442 \u0434\u0435\u043c\u043e-\u0441\u0430\u0439\u0442<\/u><\/a>.<\/p>\n<p><strong>\u041b\u043e\u0433\u0438\u043d:<\/strong> <a href=\"mailto:demo@example.com\"><u>demo@example.com<\/u><\/a><\/p>\n<p><strong>\u041f\u0430\u0440\u043e\u043b\u044c:<\/strong> demo1234<\/p>\n<p>\u0414\u0435\u043c\u043e-\u0432\u0435\u0440\u0441\u0438\u044e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c. \u041d\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u043d\u0435\u0439.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u042f \u043f\u043e\u0434\u0435\u043b\u0438\u043b\u0441\u044f \u0445\u0438\u0442\u0440\u043e\u0441\u0442\u044f\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 AGIMA \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e. <a href=\"https:\/\/habr.com\/ru\/companies\/agima\/articles\/803535\/\">\u041e \u0442\u043e\u043c, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0434\u0430\u0448\u0431\u043e\u0440\u0434 \u0438 \u043a\u0430\u043a \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u0433\u0430, \u043d\u044c\u044e\u0431\u0438\u0437-\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440 AGIMA \u0412\u0438\u0442\u0430\u043b\u0438\u0439 \u0414\u043e\u0449\u0435\u043d\u043a\u043e.<\/a><\/p>\n<p>\u042d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u043f\u0440\u043e\u0434\u0430\u043a\u0442-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430\u043c, \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0438 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0430\u043c, \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0430\u043c. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0432\u0441\u0435\u043c, \u043a\u0442\u043e \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0444\u0438\u043d\u0430\u043d\u0441\u0430\u043c\u0438 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d, \u2014 \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437 \u043f\u043e\u043c\u043e\u0449\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u043b\u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u043e\u0432.<\/p>\n<p><em>\u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u0437\u0430\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445. \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043d\u0430 \u0432\u0441\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c. \u0410 \u0435\u0449\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0439\u0442\u0435\u0441\u044c <\/em><a href=\"http:\/\/@product_agima\"><em><u>\u043d\u0430 \u043d\u0430\u0448 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0442\u043e\u0432<\/u><\/em><\/a><em>. \u0422\u0430\u043c \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0445 \u0438 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0430\u0445. <\/em>  <\/p>\n<h3>\u0427\u0442\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c<\/h3>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/751352\/\"><u>https:\/\/habr.com\/ru\/articles\/751352\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.getgrist.com\/\"><u>https:\/\/www.getgrist.com\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/support.getgrist.com\/\"><u>https:\/\/support.getgrist.com\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.metabase.com\/docs\/latest\/\"><u>https:\/\/www.metabase.com\/docs\/latest\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/pramsey\/pgsql-http\"><u>https:\/\/github.com\/pramsey\/pgsql-http<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/goauthentik.io\/\"><u>https:\/\/goauthentik.io\/<\/u><\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/803521\/\"> https:\/\/habr.com\/ru\/articles\/803521\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0415\u0436\u043a\u043e\u0432, \u044f Backend-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 <a href=\"https:\/\/clck.ru\/39iHe4\">AGIMA<\/a>. \u0417\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0410 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u2014 \u043d\u0430\u0448\u0435\u0439 DWH-\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439. \u041c\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0435\u0435 \u0438\u0437 Open-source \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0445\u0438\u0442\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438 \u0438 \u043a\u0430\u043a \u0432\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u043c\u0435\u0441\u0442\u0435.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 DWH<\/h2>\n<p>DWH (Data Warehouse) \u2014 \u044d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0447\u0435\u0441\u043a\u043e\u0439 \u043e\u0442\u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 DWH \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044f\u043c \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/agima\/articles\/803535\/\"><u>>> \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043d\u0430\u0448 \u043d\u044c\u044e\u0431\u0438\u0437 \u0412\u0438\u0442\u0430\u043b\u0438\u0439 \u0414\u043e\u0449\u0435\u043d\u043a\u043e.<\/u><\/a><\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0431\u0430\u0437\u0435 \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0440\u0430\u0441\u0445\u043e\u0434\u0430\u0445 \u0438 \u0434\u043e\u0445\u043e\u0434\u0430\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0443 AGIMA. \u042d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0438 \u0438\u0445 \u043d\u0435\u043c\u043d\u043e\u0433\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0447\u0438\u0441\u0442\u043a\u0438 \u0438\u043b\u0438 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b DWH.<\/p>\n<h2>Grist<\/h2>\n<p>Grist \u2014 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430. \u041f\u043e \u0441\u0443\u0442\u0438, \u044d\u0442\u043e \u0433\u0438\u0431\u0440\u0438\u0434 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u2014 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435, \u043a\u0430\u043a Google Sheet \u0438\u043b\u0438 Excel. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<ol>\n<li>\n<p>\u0421\u0442\u043e\u043b\u0431\u0446\u044b \u0432 Grist \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u0411\u0414: \u043e\u043d\u0438 \u0438\u043c\u0435\u044e\u0442 \u0438\u043c\u0435\u043d\u0430 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043e\u0434\u0438\u043d \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u043f\u043e \u0444\u043e\u0440\u043c\u0443\u043b\u0435 \u2014 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435: \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u044f\u0447\u0435\u0435\u043a, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412 Grist \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 Python, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 Excel. \u0412 \u043e\u0441\u043d\u043e\u0432\u0435 Grist SQLite. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u044e\u0431\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0447\u0438\u0442\u0430\u0442\u044c SQLite, \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u0442 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 Grist.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0434\u0435\u0441\u044c \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0445\u043e\u0441\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0423 Grist \u0445\u043e\u0440\u043e\u0448\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 <a href=\"https:\/\/support.getgrist.com\/api\/\"><u>API<\/u><\/a>. \u0410 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Excel \u0438 Google-\u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 Grist \u2014 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. Grist \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u043c\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u044f\u043c\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c, \u0441\u0442\u043e\u043b\u0431\u0446\u0430\u043c \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u044f\u0447\u0435\u0435\u043a \u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c SSO-\u043b\u043e\u0433\u0438\u043d (\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/goauthentik.io\/\"><u>authentik<\/u><\/a>) \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/gristlabs\/grist-omnibus\"><u>\u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/u><\/a>. <a href=\"https:\/\/support.getgrist.com\/install\/saml\/#example-authentik\"><u>\u041c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 Grist \u0432 authentik<\/u><\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c Grist, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Docker:<\/p>\n<pre><code class=\"bash\">docker pull gristlabs\/grist docker run -p 8484:8484 -v $PWD\/persist:\/persist -it gristlabs\/grist<\/code><\/pre>\n<p>Grist \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 http:\/\/localhost:8484. \u0412\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#8212; v<code>$PWD\/persist:\/persist.<\/code> <\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 Grist<\/h3>\n<p>\u0414\u043b\u044f \u0443\u0447\u0435\u0442\u0430 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 \u0438 \u0434\u043e\u0445\u043e\u0434\u043e\u0432 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u043b \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043e\u043a. \u0423 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043f\u043e\u0438\u0441\u043a\u0443:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u0431\u043b\u0438\u0446, \u043a\u043e\u043b\u043e\u043d\u043e\u043a, \u0441\u0442\u0440\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u0431\u044b\u0441\u0442\u0440\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>Grist \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u043d \u0438\u043c\u0435\u0435\u0442 \u0433\u0438\u0431\u043a\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0440\u0430\u0441\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438, \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u044f\u0447\u0435\u0439\u043a\u0438, \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0443\u043b\u044b, \u0438\u043c\u0435\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b, \u0438\u043c\u0435\u0435\u0442 \u0433\u0438\u0431\u043a\u0438\u0439 API, \u0430 \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/github.com\/gristlabs\/py_grist_api\"><u>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043d\u0430 Python<\/u><\/a>.<\/p>\n<h3>\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Grist<\/h3>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0434\u0443\u043c\u0430\u043d\u044b.<\/p>\n<p>\u0412 Grist \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u043b\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438, \u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438\u00bb.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u043a\u043d\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0438\u0437 \u0440\u043e\u043b\u0435\u0439: \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446, \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c, \u0430 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0438\u0434\u0435\u0442\u044c \u0432\u0441\u0435. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0442\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u044d\u0442\u043e\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u0438\u0436\u0435 \u0432 Grist \u0435\u0441\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\u00bb. \u041d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0433\u0438\u0431\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0430\u0431\u043b\u0438\u0446, \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u0438 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0432\u0438\u0434\u0435\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u043e\u043a\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Team, \u043d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u00bb, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u044b. \u0417\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b\u00bb \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432 \u043c\u0435\u043d\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u0423\u0441\u043b\u043e\u0432\u0438\u0435\u00bb \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u043b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f Read, Update, Create, Delete:<\/p>\n<pre><code class=\"python\">user.Team.Role == \"\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\" and user.Access != OWNER and user.Name == rec.responsible and user.Name == newRec.responsible<\/code><\/pre>\n<p><strong>user.Team.Role<\/strong> \u2014 \u044d\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0443 \u043c\u044b \u043f\u043e \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u0443\u044e \u043d\u0430\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0443 Role \u0432 \u0441\u0442\u0440\u043e\u043a\u0435, \u0433\u0434\u0435 email == \u201c<a href=\"mailto:a.ezhkov@agima.ru\"><u>a.ezhkov@agima.ru<\/u><\/a>\u201d.  <\/p>\n<p><strong>user.Access<\/strong> \u2014 \u044d\u0442\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0437\u0430\u0434\u0430\u043b\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u043b\u0438 \u0435\u0433\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d \u0440\u0430\u0432\u0435\u043d EDITOR, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u00ab\u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0415\u0436\u043a\u043e\u0432\u00bb \u043c\u044b \u0434\u0430\u043b\u0438 \u0440\u043e\u043b\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430.<\/p>\n<p><strong>user.Name<\/strong> \u2014 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p><strong>rec<\/strong> \u2014 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0432\u044b\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p><strong>rec.responsible<\/strong> \u2014 \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb. \u0423\u0441\u043b\u043e\u0432\u0438\u0435 <strong>user.Name == rec.responsible<\/strong> \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0443 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p><strong>newRec<\/strong> \u2014 \u044d\u0442\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442 <strong>rec<\/strong>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c, \u043f\u0440\u0438\u0447\u0435\u043c <strong>rec<\/strong> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0430 <strong>newRec<\/strong> \u2014 \u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043b \u0432\u0441\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f CRUD:<\/p>\n<pre><code class=\"python\">user.Team.Role == \"\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\" and user.Access != OWNER and user.Name != rec.responsible<\/code><\/pre>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u00bb \u044f \u0443\u0431\u0440\u0430\u043b \u0433\u0430\u043b\u043e\u0447\u043a\u0443 \u00ab\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443\u00bb \u0438 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043c\u043e\u0433\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u044b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0440\u043e\u043b\u044c\u044e \u00ab\u0411\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u00bb.<\/p>\n<p>\u041d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a\u00bb \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u0432\u0438\u0434\u044f\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u043c\u043e\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0438, \u0433\u0434\u0435 \u044f \u0432 \u0440\u043e\u043b\u0438 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e\u00bb.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u043e\u0441\u044c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u0420\u0430\u0441\u0445\u043e\u0434\u044b\u00bb, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0442\u043e\u043b\u0431\u0446\u0430 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0417\u0430\u0434\u0430\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443\u043b\u0443\u00bb. \u0412 \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0435 \u043f\u0438\u0448\u0435\u043c \u0444\u043e\u0440\u043c\u0443\u043b\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0433\u0430\u043b\u043e\u0447\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0444\u043e\u0440\u043c\u0443\u043b\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u043b\u0430\u0441\u044c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438:<\/p>\n<pre><code class=\"python\">user.Name if Table4.lookupOne(Email=user.Email).Role == \"\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\" else value<\/code><\/pre>\n<figure class=\"\"><\/figure>\n<p>\u041c\u0435\u0442\u043e\u0434 Table4.lookupOne \u0438\u0449\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb \u043f\u043e \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u0435 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 Role. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440, \u0442\u043e \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0433\u043e \u0438\u043c\u044f, \u0430 \u0435\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0432\u043e\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u00ab\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438\u00bb \u0438 \u043d\u0430\u0436\u043c\u0435\u043c Enter. \u0412 \u043f\u043e\u043b\u0435 \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439\u00bb \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043c\u043e\u0435 \u0438\u043c\u044f.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb \u0432\u0441\u0435\u043c, \u043a\u0440\u043e\u043c\u0435 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0438 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\u00bb \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0430 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0441\u0451 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c:<\/p>\n<pre><code class=\"python\">user.Access == OWNER or user.Team.Role in ['\u0411\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440']<\/code><\/pre>\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0430\u0439\u0434\u0435\u043c \u043f\u043e\u0434 \u043c\u043e\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0438 \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u043f\u0430\u043b\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00bb.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446 \u0443 \u043d\u0430\u0441 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c, \u0442\u043e \u0432 \u043f\u043e\u043b\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043d\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0430 \u0435\u0435 ID. \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0442\u0430\u0431\u043b\u0438\u0446 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\u00bb.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h3>Grist API \u0438 Airflow<\/h3>\n<p>Apache Airflow \u2014 \u044d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0447\u0438\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438 (Workflow Management Platform), \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f Airbnb. \u041e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 (Workflows) \u0432 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u042d\u0442\u043e \u0443\u0436\u0435 \u043e\u0442\u0440\u0430\u0441\u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0434\u043b\u044f \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.\u00a0<\/p>\n<p>Airflow \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0440\u044f\u0434\u043e\u043c \u0441 Grist \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Docker. \u0423 Grist \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/gristlabs\/py_grist_api\"><u>\u043a\u043b\u0438\u0435\u043d\u0442<\/u><\/a>, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Python, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u0434\u0430\u0433\u0430\u0445 Airflow, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435.\u00a0<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 py_grist_api, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0434\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u00bb, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f GRIST_API_KEY \u0441 \u043a\u043b\u044e\u0447\u043e\u043c API. \u0422\u0430\u043a\u0436\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0432 \u0444\u0430\u0439\u043b ~\/.grist-api-key. \u041a\u043b\u044e\u0447 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0432\u0438\u0434\u0430 \u0434\u0430\u0433\u043e\u0432 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437 Grist. \u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0438\u0434 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0438 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0438\u0434 \u0434\u0430\u0433\u043e\u0432 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0440\u0430\u0437 \u0432 \u0441\u0443\u0442\u043a\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a \u0441\u0442\u0430\u0440\u043e\u0439, \u043d\u043e \u0441 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0439 \u0434\u0430\u0442\u043e\u0439. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u044f, \u043a\u0430\u043a\u043e\u0439 \u0431\u044b\u043b\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0432 Grist \u0440\u0430\u043d\u044c\u0448\u0435 \u0437\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0434\u0435\u043d\u044c. \u041c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0445 DIM-\u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u0438\u043b\u0438 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430\u043c\u0438. \u0412\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0432 PostgreSQL. <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u0430\u0433\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430: <strong>schedule_interval<\/strong> \u0438 <strong>start_date<\/strong>, \u0433\u0434\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u043e Cron-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 Datetime-\u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p>\u041a\u043e\u0434 \u0432 \u0434\u0430\u0433\u0430\u0445 Airflow \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438\u0437 Grist \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441:<\/p>\n<pre><code class=\"python\">from airflow.models import Variable from grist_api import GristDocAPI   @dag(        dag_id=dag_id,        params=params,        schedule_interval='0 * * * *',        start_date=pendulum.datetime(2022, 6, 30, 0, 0, 0, tz='UTC'),        catchup=False,        render_template_as_native_obj=True,        tags=tags,    )    def grist_T_pg():        \"\"\"        ### GAD ETL: \u0412\u0441\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b        \u0412\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 Gtist \u0432 PostgreSQL        \"\"\"         @task()        def extract(**context):            \"\"\"            #### Extract task            \u041f\u043e\u043b\u0443\u0447\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 Grist \u043f\u043e API            \"\"\"            SERVER = Variable.get('API_URL_grist')            DOC_ID = Variable.get('GRIST_DOC_ID')             api = GristDocAPI(                DOC_ID,                server=SERVER            )             data = api.call(f\"tables\/{context['params'].get('grist')}\/data\")             return data<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-372050","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/372050","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=372050"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/372050\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=372050"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=372050"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=372050"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}