TGViewer
Channel Public Channel
Сибирский Dev | IT survival

Сибирский Dev | IT survival

@sibdevjun

Выживач в IT. Мои мысли по найму и работе в мире разработки.

Для связи @masian4eg
Subscribers
642
Photos
401
Videos
23
Links
123

Showing posts older than #419 · Back to latest

Older Posts 10 shown
Post #418 459
🕋 Стыдно такое не знать...

...спустя 3 года работы в IT. И даже не не хочется оправдываться онлайн курсами)

#конспект #SQL

Представления

Работая с SQL запросами я понимал, когда читал уже написанные или если задача была сложнее обычного селекта из одной таблицы, то я просто обращался к ИИ за помощью 🫠
Но какие же вещи я упускал и не понимал...

При работе с базами данных зачастую приходится многократно выполнять одни и те же запросы, которые могут быть весьма сложными и требовать обращения к нескольким таблицам. Чтобы избежать необходимости многократного формирования таких запросов, можно использовать так называемые представления (views).

CREATE VIEW имя-представления [ ( имя-столбца [, ...] ) ] AS запрос;

Теперь мы можем вместо написания сложного первоначального запроса обращаться непосредственно к представлению, как будто это обычная таблица.

SELECT * FROM имя-представления;

В отличие от таблиц, представления не содержат данных. При каждом обращении к представлению в команде SELECT данные выбираются из таблиц, на основе которых это представление создано.

СУБД PostgreSQL предлагает свое расширение команды CREATE VIEW, а именно — фразу OR REPLACE. Если представление уже существует, то можно его не удалять, а просто заменить новой версией. Однако нужно помнить о том, что при создании новой версии представления (без явного удаления старой с помощью команды DROP VIEW) должны оставаться неизменными имена столбцов представления. Если же вы хотите изменить имя хотя бы одного столбца, то сначала нужно удалить представление с помощью команды DROP VIEW, а уже затем создать его заново.

PostgreSQL предлагает свое расширение — так называемое материализованное представление. Упрощенный синтаксис команды CREATE MATERIALIZED VIEW, предназначенной для создания материализованных представлений, таков:

CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] имя-мат-представления
[ ( имя-столбца [, ...] ) ]
AS запрос
[ WITH [ NO ] DATA ];

В момент выполнения команды создания материализованного представления оно заполняется данными, но только если в команде не было фразы WITH NO DATA. Если же она была включена в команду, тогда в момент своего создания представление остается пустым, а для заполнения его данными нужно использовать команду REFRESH MATERIALIZED VIEW.

Материализованное представление очень похоже на обычную таблицу. Однако оно отличается от таблицы тем, что не только сохраняет данные, но также запоминает запрос, с помощью которого эти данные были собраны.

Если впоследствии вам потребуется обновить данные в материализованном представлении, то выполните команду

REFRESH MATERIALIZED VIEW имя-мат-представления;


Кстати, пишу конспекты уже прочитав книгу, поэтому пробегаюсь по ней вторым заходом и нахожу места, которые пропустил/не так понял. Полезное закрепление получается 😅
  • 🔥 9
  • 👍 3
  • 🦄 1
Post #417 379
😲SOLID ВСЕ?

На прошлой неделе услышал фразу от нашего лида: "Если в компании работают по SOLID, то бегите с их собеседования". Но я же учил, что это основа всех приложений... ☝️

Решил узнать еще мнений и понять - почему так?

🟢Принцип единственной ответственности
«У класса не должно быть более одной причины для изменения». Другими словами, у каждого класса должна быть только одна ответственность

class Calculate:
def add(a: int, b: int) -> int:
return a + b
def sub(a: int, b: int) -> int:
return a - b

Вроде бы ответственность у класса одна - вычислять, но тут 2 разных метода 🤔
На самом деле, этот принцип работает в моменте - что нужно от класса на данный момент (YAGNI). Но что, если через месяц бизнесу потребуется, чтобы мы добавили методы умножения и деления?... 😈

🟢Принцип открытости/закрытости
«Программные объекты должны быть открыты для расширения, но закрыты для модификации»

class Operation(Protocol):
def compute(self, a: int, b: int) -> int:
...

class Add:
def compute(self, a: int, b: int) -> int:
return a + b

class Sub:
def compute(self, a: int, b: int) -> int:
return a - b

def calculate(op: Operation, a: int, b: int) -> int:
return op.compute(a, b)


Тут все ок, принцип открытости/закрытости соблюдается 😎
Но приходит бизнес и говорит - в следующем релизе нужно добавить расчет отношения a от 100 и b от 100... Но у нас же уже сделан интерфейс с 2 аргументами, а теперь надо еще и с одним 😫

🟢Принцип подстановки Барбары Лисков
«функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом»

class Animal(Protocol):
@staticmethod
def move() -> None:
...

class Mammal:
@staticmethod
def move() -> None:
print("walk")

class Fish:
@staticmethod
def move() -> None:
print("swim")

def how_it_move(animal: Animal) -> None:
animal.move()


Все опять по принципу 👍 Но некоторые млекопитающие плавают или летают, а есть птицы которые ходят... А есть которые вообще не двигаются и наш метод move не подойдет для них 😍

Опять же, в моменте можно сделать по требованию, но спланировать потребности на будущее - невозможно 🤦‍♂️

🟢Принцип разделения интерфейса
«Программные сущности не должны зависеть от методов, которые они не используют»

class Animal(Protocol):
def move(self):
...
def eat(self):
...
def grow(self):
...
def reproduction(self):
...


Сделал ты такой по принципу класс, но тут вспоминаешь "есть же животные, которые не двигаются!" - делаешь отдельный класс для движимых животных с этим методом.

Приходит заказчик и просит добавить еще растения 😲 Отделяешь grow и reproduction.

Пользователи начинают строчить в техподдержку: "Почему вы не учитываете бесплодных животных???". Надо отделять метод reproduction 😠

Насколько надо гибко настроить интерфейсы, чтобы все учесть сразу?🤦‍♂️

🟢Принцип инверсии зависимостей
«Положитесь на абстракции, а не на что-то конкретное»

class Operation(Protocol):
@staticmethod
def compute(a: int, b: int) -> int:
...
@staticmethod
def name() -> str:
...

class Add:
@staticmethod
def compute(a: int, b: int) -> int:
return a + b
@staticmethod
def name() -> str:
return "Add"

def calculate(op: Operation, a: int, b: int) -> int:
print(f"Running {op.name}")
return op.compute(a, b)


Пример утрированный, но для понимания подойдет)
Наша программа должна запускаться на интерпретаторе от 3.6 и выше, так как f-строки поддерживаются только с этой версии. Но появляются заказчики, которые не могут обновиться, но хотят пользоваться и заплатить за наш продукт 🤑
Получается, мы должны предусмотреть использование и на старых версиях питона? А что, если этого никогда не случится, то мы нарушим YAGNI? 😄

Все это написано по материалам изученным в интернетах и не является дискредитацией SOLID. Он упрощает разработку и систематизирует ее, но упарываться им не стоит 100% 🧘
  • 🤯 4
  • 👍 2
  • 🤔 2
  • 🔥 1
Post #415 439
👍 Генератор схем БД

Надоели ежедневные новости и подборки очередного ИИ инструмента, но это стоит того (сам попробовал, скрин прилагаю 😎)

Встала у вас задача создать приложение или перестроить схему БД, а может вы уже это сделали, но хочется себя проверить?

Заходим в Database Build, пишем обычным человеческим языком о чем ваше приложение - получаем готовую схему и миграции, PROFIT! 🌈

Я вот на примере Fibonacci написал небольшой промпт и схема на 95% сходится с текущей

Можно править, генерить фейковые данные, импортить из CSV и деплоить в Supabase в один клик ☕️
  • 🔥 4
  • 🤩 2
  • 🦄 1
Post #414 413
Я кое как уместил эту тему в один пост) Следующие темы уже будут углубляться в язык SQL и оптимизацию запросов. Будет и сложнее, и интереснее 😏
  • 🔥 1
Post #413 445
#конспект #SQL

Пропустим пару глав об основных командах создания таблиц и добавлении строк, а так же о типах переменных 🥱

Перейдем к различным видам ограничений

CHECK
Это ограничение бывает двух видов: уровня атрибута и уровня таблицы. Различие между ними только в синтаксическом оформлении: в обоих случаях в выражении могут содержаться обращения не только к одному, но и к нескольким атрибутам таблицы
CREATE TABLE progress
( ...
term numeric( 1 ) CHECK ( term = 1 OR term = 2 ),
mark numeric( 1 ) CHECK ( mark >= 3 AND mark <= 5 ),
...
);

Можно придумать для них осмысленные имена, которые облегчат понимание причин появления сообщений об ошибках
CREATE TABLE progress
( ...
mark numeric( 1 ),
CONSTRAINT valid_mark CHECK ( mark >= 3 AND mark <= 5 ),
...
);


NOT NULL
Означает, что в столбце таблицы, на который наложено это ограничение, должны обязательно присутствовать какие-либо определенные значения

UNIQUE
Такое ограничение, наложенное на конкретный столбец, означает, что все значения, содержащиеся в этом столбце в различных строках таблицы, должны быть уникальными, т. е. не должны повторяться. Ограничение уникальности может включать в себя и несколько столбцов. В этом случае уникальной должна быть уже комбинация их значений
CREATE TABLE students
( record_book numeric( 5 ) UNIQUE,
...
);

Это ограничение можно было бы записать и так, дав ему осмысленное имя:
CREATE TABLE students
( record_book numeric( 5 ),
...
CONSTRAINT unique_record_book UNIQUE ( record_book ),
...
);

В следующем примере комбинация значений серии и номера документа, удостоверяющего личность, является уникальной. Поэтому можно модифицировать определение таблицы таким образом:
CREATE TABLE students
( ...
doc_ser numeric( 4 ),
doc_num numeric( 6 ),
...
CONSTRAINT unique_passport UNIQUE ( doc_ser, doc_num ),
...
);


Первичный ключ PRIMARY KEY
Ключ может быть как простым, т. е. включать только один атрибут, так и составным, т. е. включать более одного атрибута.
При этом в отличие от уникального ключа, определяемого с помощью ограничения UNIQUE, атрибуты, входящие в состав первичного ключа, не могут иметь значений NULL. Таким образом, определение первичного ключа эквивалентно определению уникального ключа, дополненного ограничением NOT NULL. Однако не стоит в реальной работе заменять первичный ключ комбинацией ограничений UNIQUE и NOT NULL, поскольку теория баз данных требует наличия в каждой таблице именно первичного ключа
CREATE TABLE students
( record_book numeric( 5 ) PRIMARY KEY,
...
);

В случае создания составного первичного ключа имена столбцов, входящих в его состав, перечисляются в выражении PRIMARY KEY через запятую:
PRIMARY KEY ( имя-столбца1, имя-столбца2, ...)


Внешний ключ FOREIGN KEY
Внешние ключи являются средством поддержания так называемой ссылочной целостности (referential integrity) между связанными таблицами.

Создать внешний ключ можно в формате ограничения уровня атрибута следующим образом:
CREATE TABLE progress
( record_book numeric( 5 ) REFERENCES students ( record_book ),
...
);

Поскольку внешний ключ в нашем примере ссылается на первичный ключ, можно использовать сокращенную форму записи этого ограничения, не указывая список атрибутов:
CREATE TABLE progress
( record_book numeric( 5 ) REFERENCES students,
...
);

Можно определить внешний ключ и в форме ограничения уровня таблицы:
CREATE TABLE progress
( record_book numeric( 5 ),
...
FOREIGN KEY ( record_book )
REFERENCES students ( record_book )
);

Варианты удаления связанных записей из ссылающейся таблицы:
ON DELETE CASCADE - при удалении записи на которую ссылаются записи из другой таблицы они будут так же удалены
ON DELETE RESTRICT или ON DELETE NO ACTION - запрет удаления строки из таблицы А, если в таблице Б есть хотя бы одна строка, ссылающаяся на удаляемую строку в таблице А
ON DELETE SET NULL - присваивание атрибутам внешнего ключа в строках таблицы значения NULL
ON DELETE SET DEFAULT - присваивание атрибутам внешнего ключа в строках таблицы значения по умолчанию (DEFAULT), если оно, конечно, было предписано при создании таблицы
  • 👍 6
  • 🐳 3
  • 🦄 2
Post #412 326
💎 3 года трансформаций

За это время в 🟥 в нашем продукте разработку делили и собирали по разным командам 3 раза

Расскажу в каком формате уже удалось поработать

Первая итерация:
Когда я только пришел в компанию в продукт ISIM тут была одна большая команда бэков и фронтов (девопсы, тестировщики отдельно). Было все спокойно и размерено - релизы 1-2 раза в год, общая "корзина" с багами и фичами, кто освобождался брал следующую.
Плюсы:
+ команда разработки знает все, что происходит - кто какой баг фиксит, а кто какую фичу делает и что вообще происходит.
Минусы:
- слишком чилловая обстановка 🛁


Вторая итерация:
Появляется новый CTO, который делит всех на фича-команды, в которые входят: лид, 2-3 бэка, 1-2 фронта, 1-2 тестировщика. 2-х недельные спринты и за 2-3 спринта - релиз 😃
Становится немного динамичнее и как-то даже жопа подгорает на дедлайнах 😏
Плюсы:
+ разработка стала намного быстрее.
Минусы:
- разработчики изолированы от других команд
- могут быть конфликты мердж реквестов
- баги фиксить тяжелее, если они не из твоей командной фичи


Третья итерация (и по настоящее время):
Все поделены по специализации: бэкендеры, фронтендеры, тестировщики, ядро и т.д. Релизы немного "распухли" до 6-8 недель. Появились фича-оунеры.
Плюсы:
+ разработка стала более прозрачной, так как на дейликах каждый рассказывает что и где он делает и какие проблемы есть
+ немного разжало булки из-за увеличения сроков релизов
+ добавилась возможность роста, если берешь роль фича-оунера. Рулишь фичей и своей командой из бэка, фронта, ядра, тестирования
Минусы:
- ... пока не понял 🤔


Если есть какие плюсовые или минусовые истории в работе в команде - напишите, чтобы обменяться, так сказать, опытом ❤️
  • 🔥 5
  • 🦄 1
Post #411 412
#конспект #SQL

Сегодня кратко (выходные ж завтра) про подготовительные знания для развертывания БД на посгре ☕️

Для доступа к серверу баз данных в комплект PostgreSQL входит интерактивный терминал psql. Для его запуска нужно ввести команду

psql


Для получения краткой справки по всем сервисным командам нужно ввести

\?


Многие такие команды начинаются с символов «\d». Например, для того чтобы просмотреть список всех таблиц и представлений (views), созданных в той базе данных, к которой вы сейчас подключены, введите команду

\dt


Если же вас интересует определение (попросту говоря, структура) какой-либо конкретной таблицы базы данных, например, students, нужно ввести команду

\d students


Для получения списка всех SQL-команд нужно выполнить команду

\h CREATE TABLE


Восстановление БД из sql файла
-f путь до файла
-U пользователь, который будет подключаться к БД

psql -f demo_small.sql -U postgres


Подключение к БД из терминала
-U имя пользователя
-h хост с БД
-d имя БД

psql -U postgres -h localhost -d demo


Если есть какие-то команды, которые используете часто тож пишите в каменты, я что-то знал, что-то добавил от себя еще в конспект выше 1️⃣
  • 👍 5
  • 🤩 2
  • 🦄 2
Post #407 485
🐍 Очередной симулятор питона

❗️ В Steam раздают шпионский экшен, в котором нужно решать всё с помощью кода

В CodeStrike вы играете за элитного агента, действующего в мире, захваченном ИИ и алчными корпорациями

— Пишите настоящий код Python, чтобы взламывать системы, сражаться, обезвреживать ловушки, участвовать в гонках и выживать в напряженных боевых миссиях

Разрабы обещают, что игра подойдет всем — как новичкам, так и экспертам


Ознакомиться — тут.
  • 🔥 4
  • 👍 1
Post #400 554
😑 Как правильно отдохнуть?

Скоро очередные длинные выходные, поэтому расскажу немного про доклад с кодфеста "Батарейки заряжены" от Дарьи Бородиной

Ее теория строится на 3 индикатора усталости/заряженности у человека - физический, умственный и эмоциональный. И если вы устали умом, то не стоит читать книги или заниматься образованием в этот момент. Или если устали физически, то в отпуске прыгать по горам не самое лучшее решение 😄

Давайте теперь по скринам:
0. Начало

1. "Что я сейчас НЕ замечаю?"
Вопрос, который нужно задавать себе по будильнику каждый час, чтобы отвлекаться от работы. Нельзя быть погруженным в задачу постоянно 8 часов в день. Нужны постоянные разрядки.


2. Блокировщики
Не самое лучшее решение, но это программы, которые блокируют ваш экран по истечение какого то времени, и так по в цикле весь рабочий день. Но если у вас какой-то важнный созвон, то будет не очень приятно посреди звонка отвалиться)


3. Аудит календаря
Для меня тяжелое решение планировать что-то на будущее 🤪 Но те кто умеют могут попробовать этот вариант. Нужно разбавить свой рабочий график всеми видами отдыха, чтобы восполнить свои индикаторы заряда


4-5. Сундучок ресурсов
Вы можете заполнить для себя такую схему, которая будет и шпаргалкой к календарю из 3 пункта, и без календаря вы будете знать чем заняться, когда накопилась усталость или пришло время отдохнуть. Тут градация по времени отдыха и по индикатору усталости. Рядом скрин с примерами вариантов отдыха по каждому типу и долготе)


6. Пример получения нужных вам гормонов из разного отдыха 🏝

Кстати, на канале Дарьи можно получить еще много советов и получить варианты для отдыха 😎
  • 🔥 7
  • ⚡ 1
  • 🦄 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →