background top icon
background center wave icon
background filled rhombus icon
background two lines icon
background stroke rhombus icon

Download "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery"

input logo icon
"videoThumbnail Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery
Table of contents
|

Table of contents

0:00
Обзор кода Телеграм бота на aiogram 3 с прошлого видео
2:40
Middleware слои в aiogram 3
14:53
Работа с базой данных. Установка sqlalchemy, asyncpg и aiosqlite
17:51
Создание / описание моделей (таблиц) в sqlalchemy
26:30
Создание асинхронного engine и менеджера сессий sqlalchemy
35:56
Передача сессий orm sqlalchemy через middleware слой в хендлер aiogram бота
39:02
Добавление товара в таблицу базы данных
47:29
Удаление товара из таблицы
53:32
Отправка изображений ботом
56:29
Инлайн клавиатуры и кнопки в aiogram 3
1:04:14
Событие Callback Query
1:10:06
Изменение товара в БД. Модифицируем FSM на добавление/изменение товара
1:23:06
Установка PostgreSQL сервера на ПК
1:26:32
Создание базы данных в PostgreSQL и создание нового пользователя
1:33:04
Подключение бота на работу с PostgreSQL
1:36:06
Финальные тесты
Video tags
|

Video tags

telegram бот база данных
sqlalchemy
база данных
postgresql
telegram
бот
telegram бот
telegram bot python
telegram бот на python
телеграм бот на python
python telegram бот
python
телеграм бот
aiogram
aiogram 3
Subtitles
|

Subtitles

subtitles menu arrow
  • ruRussian
Download
00:00:01
Hello everyone, the Python Hub Studio channel is
00:00:03
seventh video on Telegram development
00:00:05
bot on ama third version and in this
00:00:08
video we will work with the database
00:00:10
data for our pizzeria Bot
00:00:12
connect the SQL library elkem as orm and
00:00:15
through asynchronous implementation we will
00:00:17
interact with the database as if it were
00:00:19
sqlite and postgre SQL Let's get acquainted
00:00:22
with concepts such as middleware SL
00:00:24
a new type of buttons i.e. Inline buttons
00:00:27
and a new callback query event as well
00:00:30
let's continue working with our fsm machine
00:00:32
Because there is actually a lot more there
00:00:34
interesting things in the description of the video content
00:00:37
broken down by timestamps and of course
00:00:39
all the code that will now be here
00:00:41
the start of this video is exactly the same
00:00:43
github and the code is summarized at the end of this
00:00:46
the video will also be uploaded to github link
00:00:48
in the description now let us briefly recall that
00:00:51
we already have at the moment So we have
00:00:53
there are three separate User Privat routers
00:00:55
the router is written separately for it
00:00:57
handler in the User Privat file where it goes
00:01:00
personal interaction with the user
00:01:02
There is a User Group router for it too
00:01:04
separate User Group file in which
00:01:07
group administration is described as well as
00:01:09
specialized Admin team which
00:01:11
pulls up the list of group admins to
00:01:14
to our bot in order to
00:01:16
let's say the administrator of the establishment
00:01:18
the store could via the Admin router, that is
00:01:21
there is also a separate file for him so that
00:01:23
the administrator through a personal message from the Bot could
00:01:25
interact with it adding changing
00:01:28
deleting products, that is, interacting with the database
00:01:30
data filling the range of specific
00:01:32
store We have already worked here with you
00:01:34
we have a fortune machine right now
00:01:37
there is already a fsm strategy here, let's say
00:01:40
yes, that is, not a strategy, but rather a chain
00:01:42
dialogue through which occurs
00:01:44
adding a new product to
00:01:47
directory where we create a dictionary with
00:01:49
data that we need to transfer
00:01:51
let's say write it to the database and
00:01:53
before moving on to working with the database
00:01:55
data first of all We need
00:01:57
get to know the same ones
00:01:58
intermediate layers which
00:02:00
implemented in this framework as in
00:02:02
many other frameworks are exactly the same
00:02:03
as in jang What provides us
00:02:06
special opportunity let's say
00:02:07
add some additional behavior
00:02:10
into event handling like
00:02:12
filtering and passing to the handler
00:02:14
additional objects seem to be yes
00:02:17
here the message is sent here
00:02:19
yt which is also unclear where it comes from
00:02:21
Yes here in the handler That is how he came here
00:02:23
it's all being transmitted, it's all being transmitted
00:02:26
thanks to these intermediate layers and us
00:02:28
it will be necessary here as well
00:02:30
transfer a session on working with our
00:02:33
we will do this with a database through
00:02:35
intermediate layers therefore now immediately
00:02:37
Let's get started and get to know them
00:02:39
first what is this
00:02:41
first let’s prepare the structure
00:02:43
for our project exactly the same as for
00:02:45
we have a folder with filters from the handler with
00:02:47
keyboards let's add another one here
00:02:49
folder which we call midle wares
00:02:51
and create a file here which we will call
00:02:54
Let's just say we will have this for the base
00:02:56
data middleware so we do this
00:02:58
Let's call it dbp and first of all let's look
00:03:02
in the documentation itself we need something like this
00:03:04
documentation aam here we have handling
00:03:07
events and here are middlewares here they are and what
00:03:11
the documentation tells us about this
00:03:13
starting introduction I think you will read
00:03:15
Let's look at this ourselves
00:03:16
wonderful image that
00:03:18
fully characterizes what it is and how
00:03:20
works So we get the bot
00:03:22
event from the Telegram server and gets into
00:03:25
our handler But before she gets into
00:03:27
handler It goes right here we are
00:03:28
we see a certain chain of processing one of
00:03:31
chains as we see here are
00:03:33
filters that you and I wrote, this and
00:03:35
standard filters and those we
00:03:36
made, that is, custom, that is, essentially
00:03:38
filters participate in this chain and
00:03:40
miss or do not miss events in
00:03:42
some specific handler Exactly
00:03:44
we can also add to this chain
00:03:46
another additional behavior that
00:03:48
called midle rare that is
00:03:49
intermediate layer that makes
00:03:51
anything at all over any update and
00:03:54
middleware is important here
00:03:56
software can also be middleware
00:03:58
A or iner, that is, the difference is that
00:04:02
outer middleware work before filters
00:04:04
iner after So let's look at
00:04:07
example and let's figure out how it is
00:04:09
it works let's go below and there it is
00:04:11
one standard basic example which
00:04:14
here provided essentially if we we
00:04:16
now let's see it's very similar but
00:04:18
very similar to how we wrote with you
00:04:20
the custom filter is inherited only by us
00:04:23
not from the filter but from Base middleware here
00:04:25
implement the init method if we need it and
00:04:28
then overloading the asynchronous Call method
00:04:31
basically everything is the same only here
00:04:33
let's give some additional parameters
00:04:34
I’ll copy this completely from here now
00:04:37
Let's move it to our edit and see how
00:04:40
work with this so move it here
00:04:42
then just comment it out
00:04:44
participate in our code in the future But
00:04:47
for example now this is very suitable
00:04:49
even first of all let's start
00:04:52
see here for each
00:04:53
parameter annotation types and some
00:04:55
needs to be additionally imported
00:04:57
so let's import now
00:04:58
skylab
00:05:01
and so on from the typing module like this
00:05:03
this is how it looks From
00:05:06
typing Call everything So And now about
00:05:09
directly from the midle So
00:05:11
the name is broad as it suits you
00:05:13
but we definitely inherit from Base midle
00:05:15
So the init method code is in the init method
00:05:18
runs only once at startup
00:05:20
Bota yes When does registration take place?
00:05:22
this midle and distance are exactly the same as BMX
00:05:26
filters we
00:05:27
reu here pame then handler Where
00:05:30
comes exactly automatically
00:05:32
handler instance is forwarded
00:05:35
that is, what event was it?
00:05:37
be a mess callback quy and so on we are with
00:05:40
this is what we will be working on now and date What
00:05:42
date is a special dictionary
00:05:44
which contains all the same
00:05:47
things that can be transferred to
00:05:48
handler Here they are State and so on Then
00:05:52
there are all the intermediate layers added to
00:05:54
this dictionary in turn those data
00:05:56
which are written in them add to it
00:05:58
and he will say So this dictionary one by one
00:06:01
throws between them each other and
00:06:04
they can add their own stuff there
00:06:06
objects for example what is written in this
00:06:09
the method that is called
00:06:11
automatically when it comes to
00:06:14
of this layer what we do is Self Counter
00:06:17
increase the value by one and then
00:06:19
there is a variable like this here and then
00:06:21
we can any object let this
00:06:24
pass the variable to the dictionary date
00:06:26
give it the name Counter, that's it
00:06:29
assign a value there and then
00:06:31
definitely necessary Here via
00:06:33
the evate operator calls the handler object then
00:06:36
there is a way to pass it on down the chain
00:06:38
processing by transferring there directly
00:06:40
the event itself and the dictionary date and to do
00:06:44
Ren this whole thing Let's
00:06:46
register this middle layer and
00:06:48
Let's see how we can work with it
00:06:50
go to the App file and now about
00:06:53
external and that is outer and inner
00:06:56
middleware So let's open the document again
00:06:58
and what is written here is the bottom example
00:07:01
immediately after this after this sample
00:07:03
the code says router route yes that is
00:07:05
some kind of router is created and then the router
00:07:07
point we record the type of event That is
00:07:09
this is message for example sending a message
00:07:11
point middleware And indicate here
00:07:13
Counter middleware That is simple
00:07:15
we essentially register this intermediate
00:07:18
the layer behind this type of event is precisely for
00:07:20
this router this way
00:07:22
it is inner Middle Work that is registered
00:07:25
That is, those who have already passed the filters
00:07:27
register our layer as admin
00:07:30
router and see what we have there
00:07:32
there is a filter that works for admin AND
00:07:34
Now we can definitely check that everything is
00:07:36
this is exactly how it works How it works
00:07:38
do where exactly to register we
00:07:40
we can register it here in the file
00:07:42
Admin prat where we hang here
00:07:44
filter, that is, write it down here yes
00:07:46
With this line Or we can do it here in
00:07:49
App file let's just say this before
00:07:52
connection before registering yourself
00:07:54
We will record routers at the main dispatcher
00:07:57
here AD route mess event and call
00:08:03
here is the method for registering middleware
00:08:05
look here there are two methods This one
00:08:08
middleware that is written is already the same
00:08:10
which will work after filters
00:08:12
if we choose middleware then this
00:08:14
then we will register it
00:08:17
intermediate intermediate layer behind this
00:08:19
router but it will work until
00:08:21
filters So let's use
00:08:24
just midle like this and here
00:08:27
we'll pass on our la Counter middleware
00:08:30
we call him here and of course not
00:08:32
we forget to import it, that is
00:08:34
middlewares should look like this
00:08:36
Database since we created Counter
00:08:38
midle Great, let's just put this in
00:08:41
here below here
00:08:45
so now if we want to get
00:08:48
us in the handler data from this layer then
00:08:51
Yes, here we are, creating and transmitting
00:08:54
dictionary Yes Counter and some meaning
00:08:56
then, accordingly, in some place where
00:08:58
this is for us
00:08:59
let's implement this in hand
00:09:02
which let him remove the product here
00:09:05
We write down the name of the account separated by commas
00:09:08
which we passed the annotation to the dictionary
00:09:11
it is not necessary to indicate the type and here we
00:09:12
we can do something. Well, for example, let's do it
00:09:14
Just
00:09:16
Prince Counter will be saved there simply
00:09:19
numerical value therefore no problem
00:09:21
we can do it like this, let’s launch ours
00:09:23
Bot and let's see how it works
00:09:25
and now let’s tell our bot to delete
00:09:28
the product is nothing accordingly
00:09:30
happens because this command
00:09:31
only filter passing from
00:09:33
Admin, so first we get the list
00:09:36
admins so team Emin to the group
00:09:39
Great, she left, let's go here and
00:09:42
again Well, don’t call the keyboard anymore
00:09:44
we'll just delete the product And we see
00:09:47
we got one printed from there
00:09:49
precisely from our intermediate layer
00:09:51
two and so on we we get here
00:09:54
we process some value
00:09:57
somehow update through the dictionary
00:10:00
Data throws are in the handler and in the
00:10:02
handler here we can get
00:10:05
automatically into the parameter of the same name
00:10:07
value from middleware cool
00:10:10
Here about these directly
00:10:12
There are still intermediate layers
00:10:14
some additional information
00:10:15
before moving on to working with the database
00:10:18
data is firstly necessary
00:10:20
return exactly this construction
00:10:22
That is, I mean call the handler
00:10:25
if this is not done, that is, without
00:10:26
problems can be done simply yes that is
00:10:28
here write a condition to check as
00:10:31
we have an Event here - This is a mess here
00:10:34
check the Event user ID then
00:10:37
From User and so on All these things and
00:10:39
if there is for example yes user
00:10:40
banned or something else just then not
00:10:43
call the handler automatically then
00:10:45
this update will be considered dropped
00:10:47
eat it, he’ll just throw it away and won’t let him in
00:10:49
nowhere further this is firstly secondly
00:10:51
here you can write the following
00:10:54
for example, there’s some kind of design
00:10:56
variable let it be unimportant X handler
00:10:59
and so on That is, if the handler
00:11:02
write here not just let's say so
00:11:04
invisible yes here that is when you are not
00:11:06
specify the Return statement here
00:11:08
automatically as if under each function
00:11:10
it implies that it returns
00:11:12
Return Non from here from handler via
00:11:14
operator can return any
00:11:16
the meaning is exactly here further back
00:11:19
or rather in the middleware here it is somehow
00:11:21
further refinement If suddenly it is necessary
00:11:23
again, if this is needed, this is the first thing
00:11:26
as I said here earlier you can
00:11:29
register this middleware
00:11:31
not just like midle Yes it's automatic
00:11:34
is considered in that is already which
00:11:35
works after filtering And here you can
00:11:38
use the method specifically for
00:11:41
this one like this midle specifically for this
00:11:44
router and then now I
00:11:51
restarting as admin doesn't work because
00:11:54
that the bot is a loss let's say the list of admins
00:11:57
deputy here to remove the product that is not
00:12:00
it will work, we will send it many times, delete it
00:12:03
goods here Yes, let's say so for us Print is not
00:12:06
is displayed Because now it's up to the handler
00:12:08
Let's just say it doesn't work out but
00:12:09
the intermediate layer continues to work
00:12:12
and the counter is counting now let's return it here like this
00:12:18
list of admins for our Bot like this
00:12:21
let's go back to the bot and again
00:12:23
we send him to remove the product And we see
00:12:26
it's already 15
00:12:27
it will work, that is, well, not approximately, but
00:12:30
exactly so wonderful now next
00:12:33
moment other than hanging intermediate
00:12:36
layers directly on routers is
00:12:38
you can do it on the root router then
00:12:40
available on our dispatcher and available here
00:12:42
small One small difference
00:12:45
Let's turn now to the dispatcher To
00:12:47
the dispatcher has the same thing
00:12:49
breakdown by event mess Edit mess and
00:12:52
so on but the dispatcher also has
00:12:54
is one global event that
00:12:56
is called an update that represents
00:12:58
any event that can
00:13:00
be and mess IT message any and here already
00:13:04
can be hung just like
00:13:06
middleware after filters have been processed and
00:13:08
alter middleware where to transfer it
00:13:12
so our intermediate layer and like this
00:13:15
the intermediate layer fires earlier
00:13:17
everyone That is, he updates everyone
00:13:20
who just come to the bot
00:13:22
manipulates but in this case if you
00:13:25
hook the layer at such an early stage let's say
00:13:28
so processing events directly
00:13:31
ourselves
00:13:32
frameworks mess yes that is here and so
00:13:36
further Everything is here and ty we are here This is
00:13:39
we transfer everything here so that
00:13:40
a pro-event is necessary here Well, let's say
00:13:43
it will be more convenient for you, that is
00:13:45
record here we record the ancestor of all
00:13:48
types of events, that is, messen, it doesn’t matter
00:13:50
there are all telam object That's it
00:13:52
accordingly here
00:13:54
here and here
00:13:57
let's just say it's all normal
00:14:00
autocomplete and others let's say
00:14:02
engine compartment things worked fine
00:14:05
write here like this Telegram object
00:14:07
And then everything is basically as usual with
00:14:09
we're done with this now next now
00:14:12
let's move on to working with the database and
00:14:14
Of course, with midle wi layers we move on
00:14:16
we will already work in the context of
00:14:18
work with our database if suddenly
00:14:20
that now everything is not clear yet We are
00:14:22
Let's look at this in more detail using an example.
00:14:25
video further I will comment on this
00:14:28
Let's just say it will be on Github so that
00:14:31
don’t copy it personally and all this is possible
00:14:33
was to pierce so I’ll immediately remove it from Admin
00:14:36
private this thing and the parameter
00:14:41
from here we remove it, it won't be there anymore
00:14:43
We will then transfer the session here
00:14:45
database is excellent And that's us too
00:14:48
we clean it up, we cleaned it all up like this now
00:14:52
let's start working with
00:14:54
database We will need now
00:14:56
install with you bit first with the base
00:15:00
we will not work with data through SQL
00:15:03
requests A through the or system therefore
00:15:05
write it down So you and I need
00:15:08
install a library like this
00:15:12
SQL so that we can use
00:15:15
Python code to generate SQL
00:15:17
queries and did not bother with SQL code
00:15:20
now and now about the types of databases
00:15:22
data with which we will work
00:15:24
firstly, since it is a system
00:15:26
automatically let's say appropriate
00:15:29
code for the engine you are using
00:15:32
why am I database are different yes Well in
00:15:35
anyway it will happen now
00:15:36
relational databases based on
00:15:38
SQL but there is SQL Yes there is mysql Mar db SQL
00:15:44
they all have their own engine and that's why
00:15:46
see What is the point of working through orm
00:15:50
the requests look the same. That is, you have
00:15:52
your code does not depend in any way on the database itself
00:15:54
data, that is, essentially. Now I’ll show you
00:15:57
We are happy to work with the database
00:16:00
sqlite let's start so now for now for now
00:16:03
development it was simpler and in the same
00:16:06
video let's move on to pog SQL as you
00:16:09
asked for this to be on pog SQL
00:16:11
let's do it like this And the code itself is the most
00:16:14
interesting work with a database in general
00:16:17
will not change in any way, that is, here
00:16:19
already look further while you
00:16:21
Are you developing, are you training, are you working?
00:16:23
with a SQL database is it necessary or not?
00:16:27
Let's just say this if you want to try
00:16:29
then Use but in fact When you have already
00:16:31
will upload your Bot Yes to
00:16:34
you will already have some kind of server here
00:16:35
ready code orm system and therefore it
00:16:38
will automatically pick up that database
00:16:40
which you Connect on the server So
00:16:43
let's get started as we are
00:16:45
we will work asynchronously then we will record
00:16:47
the next one is for working with sqlite 3
00:16:50
We need Pip Install So
00:16:53
write the following library
00:16:57
iql so that we are with this database
00:17:00
data worked
00:17:03
asynchronously there is and I'm right now
00:17:05
I'll install another library for that
00:17:07
so that later she can work with SQL
00:17:10
called
00:17:12
so PG like this
00:17:16
let's go So it's all set beer
00:17:19
I won’t update. Everything seems to work.
00:17:21
ok Now we need
00:17:23
prepare the structure, that is, create
00:17:25
the folder we call
00:17:30
and here we will need the files first
00:17:32
where we will be directly
00:17:34
I'll record the launch of the engine itself
00:17:36
system for it to start
00:17:38
work like this we'll write it down So we'll have it
00:17:41
File Engine
00:17:42
then for now we will only write the Second file
00:17:46
which we will call Models
00:17:48
where we will describe the tables with you Yes
00:17:50
with the help of Penov’s Models classes everything
00:17:54
And now let's start describing our
00:17:56
tables for starters, look now we
00:17:59
we will actually use
00:18:01
There are a lot of examples of working with Christmas trees
00:18:04
they are all a little different because Nana
00:18:06
is constantly changing and now we will
00:18:07
use the latter let's say
00:18:10
option to work and create tables
00:18:13
declarative latest release which
00:18:15
took place there recently in the general version
00:18:17
2 this will be sample SQL version 2 code for
00:18:21
let's start now let's create a class, let's say
00:18:24
which will describe exactly our
00:18:26
the table we need we need a table
00:18:29
for products to start table for
00:18:31
products in which there will be a distribution of the product
00:18:34
Let's just say the serial number Yes in
00:18:35
the database is also the identifier and will be
00:18:38
name description price and
00:18:42
image record the class right here
00:18:46
I’ll write these parentheses because we
00:18:48
it will be necessary to inherit here
00:18:51
for now let's throw in a plug and
00:18:54
Let's figure out how this happens
00:18:56
directly to us first
00:18:59
it is necessary to create, let's say, a superclass
00:19:01
in front of our class Class
00:19:04
Base from which it no longer comes
00:19:07
inheritance of all classes that
00:19:08
describe the tables, create a class here
00:19:11
Base and here we inherit it exactly in
00:19:14
this class is from the class that is in
00:19:16
the library itself so declarative Base
00:19:20
Here
00:19:21
he import it from SQL alkemy orm
00:19:25
declarative Base like this so where are you
00:19:28
let's not call him, just
00:19:30
we carry out inheritance and here for now
00:19:33
just put it
00:19:34
muted we will be able to record fields
00:19:38
which are inherent to each table for
00:19:40
in order not to duplicate the code but this one
00:19:42
our class product product we inherit
00:19:45
from the newly created Base class here
00:19:47
so now we describe the next step
00:19:51
what our table will look like
00:19:53
products here in attribute
00:19:56
Table like this we will have a loan
00:20:00
let's say according to the standard for creating tables
00:20:03
in the database with a small letter in
00:20:05
singular use excellent and now
00:20:08
we need the following fields here
00:20:12
shnik
00:20:14
description so desp then to us
00:20:17
necessary Price and
00:20:20
Image and now it begins
00:20:22
interesting how to describe these tables
00:20:25
here the minimum entry looks like cm
00:20:27
way for everyone it is already
00:20:30
there will be a field for us
00:20:32
tion is generally a regular standard table
00:20:35
and here in SQ it looks like this
00:20:37
way We just need to put
00:20:39
type annotation for each of these fields
00:20:43
using a special class M like this
00:20:48
import it exactly the same way from SQ orm but
00:20:52
I draw your attention to not calling him but
00:20:55
write square brackets here
00:20:57
so and now we will have it dishni
00:21:00
data type int we write here we can
00:21:03
just write Python data types
00:21:05
int here we will have a description string
00:21:08
and Image is also a string
00:21:11
I remind you Image it will be simple for us
00:21:13
the image is not the image itself
00:21:16
and Price is FL That's all
00:21:20
minimal recording that will already allow
00:21:22
create a system table in the database with
00:21:27
tion corresponding data types in the
00:21:30
the database will be created. That is, this
00:21:31
there will be dishni integer name War and so on
00:21:36
but how can we indicate additional
00:21:38
parameters for columns are not everything
00:21:40
correct We need it for IDIN
00:21:42
indicate that he is primary K then
00:21:44
has a primary key unique value
00:21:46
identifying each individual product
00:21:48
and separately indicate to it the auto-increment for
00:21:51
so that we don't touch this field at all
00:21:53
it automatically increased when
00:21:55
adding each new entry to
00:21:57
we write one here for this purpose
00:22:00
assignment operator and use
00:22:03
we import the function in the same way from
00:22:06
point and here we can already transmit
00:22:09
additional properties for these fields
00:22:11
firstly what do we need
00:22:13
necessary
00:22:15
here Prim is a boolean value
00:22:19
firstly and secondly the auto parameter
00:22:22
increment also pass boolean
00:22:26
knowledge to do with the remaining fields
00:22:30
which we need to correct, that is, for
00:22:32
name fields We need to indicate
00:22:34
limit on the number of character lengths
00:22:36
for the description field We need
00:22:38
indicate that this is not just Char in
00:22:40
database and this field is the text Price lot
00:22:44
type decimal and IM add some
00:22:47
additional
00:22:48
options and it will look like this
00:22:51
way now I immediately
00:22:53
import here add classes for
00:22:58
lines and For text So and now Sun This
00:23:03
let's look at these additional classes
00:23:05
imported simply from S and so on
00:23:10
Ashniko The media figured it out further So we
00:23:14
marked that this is a line but indicate
00:23:17
here are additional attributes that
00:23:19
we need them here we need them
00:23:24
others
00:23:26
150 To do this you need to go here to
00:23:29
Map col additionally pass like this
00:23:31
Let's just say the class through which it's all and
00:23:33
pass that is string 150 characters and
00:23:37
false That is, it cannot be empty
00:23:39
further description Map col simply
00:23:41
pass the class without any arguments
00:23:45
text to indicate to the database
00:23:47
that this is not a Char Yes with a limited length
00:23:50
lines And this is the text field where it can
00:23:52
a large amount of text is stored further
00:23:55
In the same way, we indicate the type
00:23:58
data FL so from SQ and indicate in
00:24:03
it has an additional parameter As
00:24:05
decimal we pass the boolean value True and
00:24:08
it cannot be empty and in the Image field
00:24:11
also indicate string Char yes For this purpose
00:24:13
to limit line length to 150
00:24:15
characters for many databases is
00:24:16
mandatory condition for the Char then field
00:24:19
there must be indicated that no more
00:24:21
than essentially our description, let’s say
00:24:23
Our table for products is all ready
00:24:26
There are fields that we need. Well, let's
00:24:28
add here Yes, it will be for now
00:24:30
this is very appropriate here in the class which
00:24:34
We created let's say it's about the parent
00:24:35
yes la Base and we like I said we can
00:24:39
we will indicate here further
00:24:41
Let's just say it's going to be big
00:24:42
number of different tables, that is, for
00:24:44
user for ordered goods and
00:24:47
so on And we may have fields
00:24:50
which are the same everywhere, but in this
00:24:52
case I want to add here in the field here
00:24:55
additional fields that indicate
00:24:58
creation of a record in the database and date
00:25:01
changes since this class product
00:25:03
describing this table is inherited from
00:25:06
this class then automatically these fields are
00:25:08
are inherited and here so now I’ll explain that
00:25:11
why do we immediately import this from
00:25:14
we will be from exactly the same from here from SQ
00:25:18
see Here we will say everything by analogy
00:25:23
ation occurs
00:25:25
here we can transfer A to
00:25:29
in principle, the class of SQL itself and then Map
00:25:33
colum here we indicate that this will be Data
00:25:35
time field and default already exist in SQL
00:25:39
special function which F Now so
00:25:43
this is how the current time tightens up
00:25:47
yes it will be created automatically So
00:25:50
as when creating a record, we don’t come here
00:25:52
we will transmit no value
00:25:54
the default value will be taken
00:25:56
meaning - it will catch up in time
00:25:58
creating a record in the table And here is updated
00:26:00
essentially the same thing only here in
00:26:03
additional parameter on update again
00:26:05
indicate F Now this will also happen
00:26:07
happen automatically if we
00:26:09
change the price of the product in this field
00:26:12
The update date will automatically change
00:26:15
recordings are great, we did it with you
00:26:18
we will do the rest of the tables later
00:26:20
Now we've got enough for now
00:26:22
this is exactly what we created in the file
00:26:25
Models now go to File Engine and
00:26:29
we are preparing to launch the orm engine
00:26:33
the code here will look like this
00:26:35
way since we work asynchronously
00:26:37
then the following happens firstly
00:26:39
Engine variable here we call
00:26:42
special Create Engine function
00:26:44
which we ourselves import from SQL
00:26:47
nude and further here OS Get enf exactly the same
00:26:52
from the en file we will now pull it up
00:26:54
here is the URL address, that is, well, the URL where where
00:26:57
Where is this database and e for
00:27:00
so that all SQL queries that
00:27:02
are created by us and displayed in the terminal
00:27:05
the next step is to create a Session
00:27:07
the maker from whom we will take
00:27:09
sessions to make requests to
00:27:11
our database is done as follows
00:27:13
way also asynchronous asing Session
00:27:15
Maker is also imported from
00:27:18
ext then bint we bind
00:27:20
directly here the engine that we
00:27:26
initialized as we will have it
00:27:28
work asynchronously here in the class parameter
00:27:31
and the underscore is also conveyed here
00:27:33
special class yes In order to
00:27:35
specify not an ordinary but an asynchronous class
00:27:37
creating sessions Session which we too
00:27:39
import and expiring Comment
00:27:42
set to fse so that we
00:27:45
could take advantage of our session
00:27:46
again after comment yes In order
00:27:48
so that it doesn’t close immediately Great
00:27:51
Now the next step is to
00:27:53
the orm system created our table for us
00:27:56
and all the tables that
00:27:58
further will be described here in fa Mod Us
00:28:00
necessary
00:28:02
write down this construction, that is
00:28:05
write an asynchronous function, let's say cre
00:28:07
db here is according to the standard let's say this
00:28:11
always done This is standard code
00:28:13
asynchronous context manager
00:28:16
Engine as Con and further And here you need Yes
00:28:20
here you see a synchronous recording
00:28:23
function but doesn't matter That's all
00:28:25
only point nature always works like this in
00:28:29
SQ specifically This function is asynchronous
00:28:32
there is no Run and we are Accessing the Base class
00:28:36
which we
00:28:42
imported essentially create everything
00:28:44
the tables will all be automatically pulled up
00:28:46
and create it in the database as
00:28:48
an alternative just in case
00:28:51
recorded by Dr Database If suddenly
00:28:54
you need to completely delete all tables
00:28:56
which were created by the same
00:28:58
design only here Base metadata
00:29:00
Drop All and this Create db function for us
00:29:05
you need to run somewhere
00:29:07
let's run it here in the app.py file here
00:29:10
here in the Main file as it is
00:29:12
asynchronous exactly the same via evate
00:29:15
Create db like this and launch it
00:29:20
here and of course we import like this from
00:29:24
Database Engine import Create db like this
00:29:26
let's go so import now let's check that
00:29:29
everything was beautiful and here it’s ugly
00:29:32
Please note here at Engine
00:29:36
yes, it turns out a request for the URL of the database address
00:29:39
data from the file then unv from reading these
00:29:43
variables from there comes to already
00:29:46
after including this file you need it
00:29:49
change and do this
00:29:51
so that these variables are there
00:29:53
already were at the time of loading this
00:29:56
of our file everything is great but the point is
00:29:59
that again this is a little wrong
00:30:01
See the thing is that for your Bot
00:30:04
you can create two special
00:30:06
functions that run alone
00:30:07
is launched during the start of the Bot second
00:30:10
runs when it finishes
00:30:13
work and we can do it like this here
00:30:16
function Main dispatcher startup and nush
00:30:20
one hundred register manager is indicated here
00:30:23
let's create a function of the same name and
00:30:27
shutdown register on shutdown here too
00:30:30
above, yes, here we’ll write down these two
00:30:33
functions that is, you can do here
00:30:35
some things that happen on
00:30:37
startup or shutdown of your
00:30:39
Bot for example on shutdown here
00:30:41
it is necessary to transfer the Bot
00:30:43
Print for example tlx yes Or something else
00:30:46
And in the on startup function we write
00:30:49
evade Create Database run this
00:30:53
function which we
00:30:54
imported the following story like this
00:30:57
now I
00:31:03
import Database i.e. deletes everything
00:31:06
tables, we’ll just write it down through checking
00:31:08
if there is some parameter, yes then there is
00:31:11
memory that is transferred during startup
00:31:14
Bota will be there, here he is Yes, I’ll call him like that
00:31:17
I just threw it here as an example if if
00:31:20
this parameter will be equal to reset all
00:31:24
tablets before launching then Toda nacha everything
00:31:27
the tables will then be created if they are already
00:31:30
tables exist then this function
00:31:33
cre db It just won't do anything
00:31:36
yes she will look and there is a table Well
00:31:38
it means there is always something new to create
00:31:40
accordingly no one will make mistakes
00:31:41
there will be no this parameter through
00:31:44
the arps module can be passed during
00:31:46
launching the Bot That is, when you are in
00:31:47
in the terminal you type Yes there is a Python App and
00:31:52
then further as with many programs
00:31:54
put a space there and write it down
00:31:56
additional parameters That is, this is us
00:31:58
we won't do it now if you
00:32:00
you want to implement it yourself in the future, but
00:32:02
now I recommend not to do this
00:32:04
bother and now we have almost everything
00:32:06
done Now we need to specify
00:32:08
exactly db Lite for example and this one
00:32:11
variable in files with dot NV where y
00:32:14
us token to indicate the link for
00:32:17
our database so without space GB
00:32:21
let's write it down like this for now we'll work with
00:32:22
we'll do iql a little later in this video
00:32:25
post SQL connection and we need
00:32:27
pass here as a string oh or rather to us
00:32:31
you need to pass the following here
00:32:33
history for working with sqlite like this
00:32:37
like sqlite - we have single-phase
00:32:41
which here in our project will create
00:32:43
will create a file We need here
00:32:45
indicate this way
00:32:46
sqlite, that is, from which database
00:32:49
data which database we work with
00:32:52
and specify the library, that is, the engine
00:32:55
through which to work and we installed
00:32:57
it's like that
00:32:58
iql like this
00:33:02
colon three slashes and now indicate
00:33:06
the name of the file itself which is Here
00:33:08
it will be created let it be done like this mybase
00:33:13
Dot And db extension like this
00:33:17
Let's launch the Bot. Let's check what
00:33:20
now the terminal will give us the same
00:33:24
let's run let the database be created and
00:33:26
our table
00:33:28
that's a mistake
00:33:30
So it means yes it needs to be deleted
00:33:33
We don't have this anymore
00:33:37
intermediate layer So
00:33:39
delete restart I mean midle
00:33:43
layer that we Counter removed So we
00:33:45
see in the terminal We have you SQL
00:33:48
queries that were generated by or and here y
00:33:51
we came into being as mybase SQL database
00:33:56
great So now let's get at it
00:33:58
let's take a look and continue the program
00:34:00
called db browser in brackets sqlite
00:34:03
only for working with databases of the type
00:34:05
sqlite can be viewed through it
00:34:07
the contents of this database are very easy
00:34:09
and just like that Open
00:34:13
Database nata here folder Where you have
00:34:16
project and open
00:34:18
File and we see here we have one
00:34:21
products table Here it displays SQL
00:34:24
The request that was generated and
00:34:27
there is a tion field here
00:34:30
PR is excellent means everything is fine with us
00:34:33
it worked and now as the next step
00:34:35
We need to do SQL queries with you
00:34:38
that is, directly through m
00:34:40
add
00:34:42
product change and so on like this
00:34:44
is being done That is, you and I have here
00:34:48
he We are in directly in the file
00:34:51
eng and this is what it looks like singing here
00:34:57
how to interact now
00:35:00
This is how we define any function for now
00:35:04
that Yes, let's say she accepts it as
00:35:07
parameter but it is written here therefore
00:35:09
without any trickery, let’s write it down like this now and
00:35:11
now since it's asynchronous asynchronous
00:35:14
write down the contextual option
00:35:19
call the manager
00:35:25
it and now through this session object
00:35:29
special methods are now available to us
00:35:31
which allow us to make requests That
00:35:33
There is, for example, a Session that executes
00:35:37
allows you to execute the request but
00:35:39
agree, let's say it's a little awkward
00:35:41
That is, what’s next with this?
00:35:42
work and how to pass it on
00:35:44
to our bot and to our handler Exactly for
00:35:46
This is what you and I looked at about this file
00:35:50
We don't need NV anymore So do models
00:35:52
not needed yet
00:35:54
means about our midle W layers and create
00:35:57
special midle layer just for work
00:36:00
with our sessions this will look like
00:36:02
this way this is how I am now
00:36:05
import so let's import here
00:36:08
function to type annotation
00:36:10
just put it down
00:36:13
now as in the previous example which
00:36:16
here Counter so Database Session
00:36:18
let's call it Base midle, inherit it and
00:36:21
now in the init method we write
00:36:23
the Session Pool parameter in which we will
00:36:25
transferring our Session Maker is easy
00:36:28
annotation like now So let's pass it here
00:36:31
our Session Maker exactly During
00:36:33
registering this Self Session Pool layer
00:36:36
Session Pool we transfer everything and now
00:36:38
Let's implement the Call method here according to the standard
00:36:39
Self handler Event Data will be indicated here
00:36:42
Apply Telegram object to everything at once
00:36:44
so that any handler, regardless
00:36:46
depending on the type of events We could
00:36:48
forwarded
00:36:56
in this Call method we also write
00:37:00
most S is already yes by the name of the variable
00:37:03
How to continue the session then into words
00:37:06
add session by key
00:37:08
directly the session object itself and
00:37:11
handler that is, everything is as usual That is,
00:37:13
we now have a session parameter in each
00:37:17
handler that's how we are here Yes parameter
00:37:20
mess one hundred Access session will be the same
00:37:23
and register
00:37:25
this is in the appp file and here in the function
00:37:30
Main we write the following construction:
00:37:32
Now I’ll put it all on update
00:37:35
that is, at the very early stage, but how do I
00:37:37
I said you can redo this further
00:37:39
specifically, for example, under the admin router or
00:37:42
and under the User Privat router do So
00:37:47
dispatcher point on not on mess but on
00:37:49
update between hanging
00:37:52
midle after passing the filters
00:37:55
everyone, that is, not just midle
00:37:57
and now our Database Session layer
00:38:01
register it like this and import it From
00:38:04
midle
00:38:05
Database and pass it here as a parameter
00:38:08
Session Pool is our Maker session which is also
00:38:12
import from where
00:38:15
From
00:38:16
orm No, not from here we need it
00:38:19
import it exactly
00:38:23
from our Engine so therefore to Fix not
00:38:27
helped now let's do it so we have
00:38:30
here with
00:38:31
import Database here it is
00:38:34
let's do eng from here Why doesn't he see
00:38:37
unclear
00:38:40
so here he is Session and fix everything
00:38:45
a little bit here Why did you post it like that
00:38:48
it's out of here like this
00:38:52
let's do everything beautifully now
00:38:55
us exactly in every handler who gives us
00:38:58
required for example yes here in the admin panel
00:38:59
will be forwarded
00:39:19
the last state of the user and ours
00:39:22
a dictionary with data is formed here
00:39:23
which must be written to the database
00:39:25
data so from here Print is superfluous
00:39:28
delete it, correcting the code a little And now
00:39:31
we are here Add Image Yes this is a function
00:39:34
handler here is the message State parameter AND
00:39:37
just like that we are here now
00:39:38
we pass the session parameter in order to
00:39:42
it was convenient for us, we can convey here
00:39:44
annotation for him
00:39:46
like let's make it as simple as possible
00:39:49
specify this I Session from SQL alch
00:39:55
so here it is, here it is, this import
00:39:58
great, separate him from here and now what
00:40:02
we do We have processors here
00:40:05
just as an annotation like this now
00:40:07
we get a dictionary with data now
00:40:09
it must be written accordingly
00:40:11
now here below we write
00:40:13
the following design We turn to our
00:40:15
sessions for now we'll record it here in
00:40:17
handler yes In order for it to be like
00:40:19
it would be more clear That is, you can write
00:40:21
requests specifically to the database in the handler
00:40:24
or you can put it in a separate file
00:40:26
Now let's see how and this and this
00:40:28
do We turn to the session and here there is
00:40:30
the first is the simplest method, let's say
00:40:33
which allows you to add an object to the database
00:40:35
data is the Add method where necessary
00:40:38
pass the object itself let's say
00:40:41
product yes, that is, we turn to the database
00:40:43
data to our product table which
00:40:45
us is described by the class of product we
00:40:47
import from Database Mod that is
00:40:49
from here where we produce here from Mod
00:40:53
Ir And now here to convey our this
00:40:57
formed object So we point
00:40:59
above Let's look Yes, instance is indicated here
00:41:02
yes this is the first parameter where you need it
00:41:04
pass the object itself Here it is object
00:41:06
the element in the database is described by us
00:41:09
using class
00:41:11
product now accordingly We are here And
00:41:14
we list the data from ours like this
00:41:17
dictionary Data name Data name description
00:41:19
Data description Price and so on
00:41:22
means Price is translated here separately
00:41:25
since it is indicated there in our database
00:41:27
specifically yes numeric floating
00:41:30
dot data type after
00:41:32
an object has been added, let's say now
00:41:34
you need to save the changes to this
00:41:36
sessions here we already need through
00:41:38
aate operator access session
00:41:41
Session and produce a cat that is
00:41:43
pinning the data to the database like this
00:41:47
that's all And this is how the product will be added
00:41:50
that is, a record of the product will be added to our
00:41:53
You can do this in several ways
00:41:55
it’s more beautiful, that is, you can’t get it here
00:41:57
create the object variable like this
00:42:01
the product itself is here So
00:42:03
why does it just look so clearer?
00:42:05
the code first created a product object
00:42:08
then we pass the Session Add here ourselves
00:42:11
object This is how we produce it later
00:42:14
Comet So, of course, this is necessary right away
00:42:16
check we launch our Bot like we do
00:42:20
we see requests to create tables are not
00:42:22
were carried out by our let's say RM system
00:42:24
just checked checked that the table
00:42:26
the product exists and that’s it And now it’s ours
00:42:29
The bot is already online, let's write to him
00:42:32
First, let's tighten up the rights through the group
00:42:35
admin so Admin let's go and start
00:42:39
add product Let's go So we have
00:42:41
here we call the keyboard in the same way
00:42:43
I remind you to start through the Admin command already
00:42:45
PM me to add product
00:42:48
let's go what we have here So we have
00:42:51
pizza tsa oh let it be added
00:42:55
description
00:43:00
price tag and now download
00:43:03
Any image will do
00:43:06
so click send product added And
00:43:10
we see displayed in our terminal
00:43:13
generated queries Excellent Now
00:43:15
As the next step, I suggest you look into
00:43:18
our database and see what it looks like
00:43:20
there we go to Data and look like this
00:43:24
Aidini pizza means Image and date
00:43:27
update created update date
00:43:29
will change, I remind you as soon as
00:43:31
something is going to change here, great here
00:43:34
everything is saved here in the database
00:43:35
great and now let's move on to
00:43:38
further work firstly What we
00:43:40
now we’ll do it right away We have it on file here
00:43:42
Database we will create a file that will
00:43:45
be responsible for these requests because
00:43:47
in fact the handler will be very strong
00:43:49
bloated if you write this whole thing here
00:43:52
so let's write down what we're doing here
00:43:55
here E f which naom
00:43:57
Ory like this then in which we will be sun this
00:44:02
write it down like this from here
00:44:04
cut out the creation of this
00:44:08
request so wrong with session com
00:44:13
fully
00:44:15
everything was cut out and moved to Ory and was the first
00:44:19
let's create a skin function here
00:44:21
asynchronous
00:44:26
so that they don’t get confused later with temples If
00:44:28
suddenly they will be of the same name for example
00:44:31
yes, we write here with this prefix
00:44:34
very comfortably
00:44:37
or This is how we will transfer here
00:44:42
directly our session for her
00:44:45
let’s write the same type annotation for
00:44:48
so that we can be comfortable here
00:44:50
work with methods we produce irgo
00:44:53
this
00:44:54
de
00:44:56
here in addition to the session itself We need
00:44:59
the dictionary itself will be the date itself
00:45:01
Yes, we also sweat it like di and now that’s all
00:45:05
what we cut from the handler we write down
00:45:08
here we import our proc model here
00:45:11
from Database
00:45:14
Mod Sun our function is ready and now we
00:45:17
the only thing left is right here
00:45:20
wash it all down
00:45:24
Use orm Add product and produce it
00:45:29
import here from Database that's all
00:45:31
okay and of course we pass ours into it
00:45:34
the session and our data are so great
00:45:38
immediately correct the imports so that there are no unnecessary ones
00:45:40
was that we were already imported
00:45:43
here now we have the product model itself
00:45:46
it is in this file that the handler is not needed
00:45:48
we clean up and what do we need? Well, that’s all we need
00:45:52
let's go back to
00:45:54
handler just in case If suddenly Yes
00:45:57
some kind of mistake might happen
00:45:59
we write the following operator here
00:46:01
Try Try Accept the design and
00:46:04
I'll reformat it a little. It's all here
00:46:06
thus update Data that is
00:46:08
we get the data perfectly we get it
00:46:09
dictionary with data and now in
00:46:11
Try's designs record an attempt
00:46:13
writing data to the database If everything
00:46:15
ok, then we display the product added here
00:46:18
and send it back to the admin
00:46:20
keyboard and clear it if it occurs
00:46:23
there is some error then we send
00:46:25
user error message here
00:46:27
we indicate exactly the error itself so that the bot
00:46:29
sent him in chat Contact
00:46:31
to the programmer and so on and clear the stand
00:46:34
great, sorted it out, add bye
00:46:36
there are many goods, we won’t have one or two
00:46:38
that's enough and let's move on to what we have
00:46:41
further here in our in our Admin file
00:46:44
Privat So what do we have here, what do we have
00:46:46
here they are separate there is a handler So
00:46:48
which should display a list of products and
00:46:51
one of them will be change product remove
00:46:53
the goods, that is, we still need
00:46:55
additional requests namely us
00:46:57
must learn to choose from the database
00:46:59
data all the products that there are some
00:47:01
separate product AND change records in the database
00:47:05
data and delete them immediately
00:47:07
go to orm quy and I suggest now
00:47:09
do all these functions at once
00:47:12
requests for them now
00:47:14
Let's say it all at once with one glance
00:47:16
look and see the difference and so on
00:47:20
it will look like this
00:47:23
So the first function is for us to add
00:47:27
product we figured it out
00:47:28
let's move on to
00:47:30
next exactly the same all functions
00:47:32
asynchronous here we write it like this orm Get
00:47:35
products, that is, we will have this function
00:47:37
display a list of all products that
00:47:39
there is also forwarded here
00:47:44
additional functions from the orm system
00:47:47
so that we can form
00:47:48
namely the request. The first one is
00:47:50
Select function which helps us
00:47:52
generate a request for data sampling from
00:47:55
Database
00:47:56
so we import from
00:47:58
SQ doesn't work for anyone
00:48:01
such
00:48:03
From here we are immediately importing
00:48:07
here is the update function that is needed
00:48:09
to update an existing one
00:48:11
entry in the database and Delete for that
00:48:13
to remove it So let's move on to our
00:48:16
functions, we first form a request then
00:48:19
yes we do from the table we indicate here
00:48:24
simply
00:48:26
and that's it, this will be a short entry
00:48:29
means that all records from
00:48:32
this database from this table then we
00:48:35
Access our session via A
00:48:38
execute execute the request and pass it here
00:48:40
this generated request Yes this
00:48:42
the function will automatically return it here and
00:48:45
then we save this data into a variable
00:48:47
and return to
00:48:51
ours, that is, everything that is needed there
00:48:54
apply these additional methods
00:48:57
for it to be normal
00:48:58
form of a similar function only which
00:49:01
will choose some particular one
00:49:03
product that is, we see orm Get product
00:49:07
throw get from handler
00:49:09
Product ID request is absolutely correct
00:49:13
the same only here we go to the function
00:49:16
Select product rather than the method Yes this one
00:49:19
function returns class so here
00:49:20
methods further Point where proc point ID
00:49:24
equals the use like this approximately similar
00:49:27
we return it in the same way as there
00:49:30
one object will be returned
00:49:32
return the exact scalar method and continue
00:49:36
the next function is ours
00:49:39
update on any update
00:49:41
specific entry or Update product
00:49:43
forwarded
00:49:55
the next request is no longer through Select A
00:49:57
via update product Where product ID
00:49:59
equals product ID and now apply
00:50:01
the next method is the values ​​in which
00:50:04
we convey Yes, exactly the same as we did with
00:50:05
by you in the very first name Data function
00:50:08
name description Data description this is us
00:50:10
We will also do this via fsm state.
00:50:14
eat via fsm machine and then return
00:50:18
our result and then transmit this
00:50:20
request here in Session execute only
00:50:22
here it’s superfluous just A execute and
00:50:27
then C com return nothing to us in le
00:50:30
from here there will be no need for the last request
00:50:32
this is for deleting an existing one
00:50:34
entries or Del prod function
00:50:37
forwarded
00:50:49
and now we return back to our
00:50:54
x meaning Now there will be further actions
00:50:57
next So these handler change
00:51:00
remove the product and just look at the room
00:51:02
see What's the point they should now
00:51:04
send us that is, in each of these
00:51:06
we will now receive handlers
00:51:08
list of all products that are available and how
00:51:11
would be separate messages from the Bot
00:51:13
send to our admin and under each of
00:51:16
under each product we will place
00:51:18
That same Eli button, that is, which
00:51:21
is attached to the text of the message on Koto
00:51:24
will
00:51:25
or delete but as you understand by
00:51:29
each message can be posted
00:51:31
several buttons, that is, simultaneously
00:51:33
under one under one message and change
00:51:35
and delete the product Well, basically
00:51:38
you can look just as well just not
00:51:40
pressing these buttons so I
00:51:42
I propose to combine these three handlers into
00:51:44
one and remove everything unnecessary from here altogether
00:51:47
what are you and I going to do now?
00:51:49
handler change and delete We are completely
00:51:51
let's remove it from here, let's do it like this
00:51:54
we won't do it here, don't look, just come in
00:51:57
we’ll just write the assortment and do the same
00:52:00
So we’ll write the same assortment on
00:52:02
button so that there are no extra ones, let's say
00:52:05
actions for the admin and for us and for everyone are easier and
00:52:08
let's leave it here it turns out only a button
00:52:11
add product AND assortment button
00:52:14
additional buttons of course
00:52:15
then if suddenly necessary they can
00:52:17
add let's do something like this
00:52:20
keyboard and place these two buttons
00:52:23
just like this so that it’s in the same row
00:52:26
their
00:52:27
two like this and now the next
00:52:30
actions on the assortment button
00:52:33
you will need to make a choice now
00:52:35
data from our database that's why we are here
00:52:37
we record our session in the same way
00:52:39
take it from the intermediate layer like this
00:52:43
we throw an annotation here and now through
00:52:46
for loop Selecting from
00:52:48
ours from our table So we write down
00:52:51
for product in here we write the operator
00:52:53
A because we don't need to call
00:52:56
here is a function that selects all our
00:52:59
records so we write product and here we have
00:53:02
there will be a function or Get
00:53:05
products That's it and of course here we are
00:53:08
we convey that we are transmitting the session so S that’s it
00:53:12
great and now the loop will work
00:53:15
It is clear that there are as many products as we have
00:53:17
then we'll do the pagination, now it will be
00:53:19
so far so
00:53:21
work back and forth and there we will have
00:53:23
Let’s say there are n products or 10 and here they are all
00:53:26
will be like separate messages from
00:53:28
Bot go and use it here
00:53:30
this way, that is, for each
00:53:32
iteration mess but not just And which
00:53:36
allows you to send a photo like me and
00:53:38
spoke through the identifier in general what
00:53:40
There are options for sending Ifa photos
00:53:44
or a string that is a string is that
00:53:46
the very identifier we get
00:53:48
through the state machine That is
00:53:49
image ID which is already
00:53:51
is on
00:53:52
server and which was sent to the bot
00:53:55
that is, the bot saw it somewhere
00:53:57
directly URL image in
00:54:00
Internet or inp F That is, this is class Yes
00:54:03
just import it from types where
00:54:05
you need to pass the location path
00:54:08
file if you have it just like this in
00:54:10
project Yes lies directly itself
00:54:12
transfer the image file to the Image product
00:54:15
we get Yes this data from the sample
00:54:18
which we get here prod Image and
00:54:21
further Caption that is description
00:54:23
directly from the image itself Here
00:54:25
we have HTML specified as a string
00:54:29
so we can do it here without any problems
00:54:30
apply one of the tags that
00:54:33
supported by telegram for
00:54:35
text formatting is STR and here
00:54:38
write down product
00:54:40
name we close n so that we say in bold
00:54:44
Yes, this particular text was highlighted further
00:54:46
move the product description line and
00:54:48
the price is indicated in rounding prod
00:54:51
Price up to two digits is absolutely the same
00:54:54
we will add the code now So now
00:54:56
I'll copy it from here, let's go straight to
00:54:59
handler where we have here Yur private there
00:55:02
where there are just users and not admins
00:55:04
it works and we have it here somewhere
00:55:07
here is the menu command here is the menu that is
00:55:09
We put absolutely the same thing here too
00:55:11
so that the user can use
00:55:13
this button and look at the menu
00:55:15
The session parameter is exactly the same here
00:55:26
so Database and so the main thing here is not
00:55:29
confuse Get prods in plural
00:55:31
number super
00:55:33
Let's launch the Bot and add another one there
00:55:36
product so that there are at least two of them
00:55:39
two is enough standard opening
00:55:41
operation to get the admin provost like this
00:55:44
to the Admin group and now add another one
00:55:47
there seems to be one already there, let’s write it like this
00:55:51
no hassle pizza like that
00:55:57
2 description
00:55:59
2 price tag and
00:56:02
image and now let's see
00:56:05
does our data sampling happen like this
00:56:07
firstly just click on the menu
00:56:08
user so twice with description
00:56:11
Great, so our assortment button
00:56:14
works works and now the next thing is
00:56:16
we will now create a button for the admin
00:56:19
assortment, he threw out two products for us
00:56:22
which are recorded in
00:56:23
database
00:56:25
such new buttons that will
00:56:27
attached to each individual let's say
00:56:30
will be attached to each individual
00:56:32
product change or delete change
00:56:35
so that the admin can do this So that means
00:56:39
Let's put it all out and go. For this we need
00:56:41
now we need line buttons buttons
00:56:44
we've already discussed this here with you
00:56:46
We’ll create a separate file for the buttons
00:56:49
here is one fa in which we will hurt another
00:56:52
buttons that are attached to the message So
00:56:58
inp Here File and now all this at once
00:57:02
Let's look at how this is actually done
00:57:04
absolutely the same
00:57:05
it looks the same way
00:57:09
right now let's do it like Exactly like this
00:57:11
what we did with the help of functions we will create
00:57:14
here for them there is also a separate button
00:57:16
let's say separately the functions for
00:57:17
generating these buttons directly from our
00:57:20
handlers so that we don’t have to worry about it later
00:57:21
in general, that is, it’s like you and me
00:57:23
They said before that we should create separate
00:57:25
sets of buttons so you can do this
00:57:28
universal what's the point
00:57:30
We won’t look at the parameters yet, let’s reverse them
00:57:32
attention to how Inlines are created
00:57:33
the buttons are the same instead of Reply
00:57:37
Keyboard Builder Yes we will
00:57:39
use Inline Keyboard Builder and
00:57:41
then we refer to this in exactly the same way
00:57:43
add a dot here to the instance
00:57:46
Inline Keyboard Button instance
00:57:49
special class for creating live
00:57:51
buttons and here look at what
00:57:54
cardinal difference if rep button She
00:57:57
the keyboard sends what's on it
00:58:00
written except points when this is a request
00:58:02
contact or user location request
00:58:05
Line buttons work differently for
00:58:07
they have a text parameter it is required
00:58:10
Yes, it's just an inscription, just an inscription on
00:58:12
button But it doesn’t send it to the chat
00:58:15
options can be passed to the URL, that is, when
00:58:18
clicking on such a button will open
00:58:20
URL address Yes on the Internet well site
00:58:23
some kind of redirection or callback
00:58:26
Data in which we indicate in the form
00:58:28
strings special meaning and when
00:58:31
pressing this button it does not
00:58:32
it is sent to the user's chat
00:58:34
sent invisibly to the user
00:58:37
to our bot and we can do the same
00:58:42
handlers for exactly this But this is already
00:58:46
separately, a completely different type of event
00:58:48
there is no mess no mess And this is Call quy
00:58:53
return request from clicking on this
00:58:54
button So let's get started
00:58:58
synthesized turning
00:59:01
functions Get buttons in our hand we
00:59:05
we will have to pass it there as a parameter
00:59:07
buttons dictionary in which we will
00:59:10
indicate text and data line
00:59:13
which will be sent to our bot
00:59:15
when you click this button and continue here
00:59:19
CEC is exactly the same. That is, how to place
00:59:22
these buttons are here
00:59:25
But item we go through this dictionary and
00:59:29
generate keyb Key
00:59:32
But parameter we pass here our string with
00:59:34
data and further keyb adj
00:59:38
siz you can make a similar one
00:59:40
function below so that it is here if
00:59:44
we will need to generate online
00:59:46
buttons with links
00:59:48
somewhere
00:59:53
That is, this is not the Data text, but the URL text
00:59:58
Let's just go here like a dictionary
00:59:59
send button label and link
01:00:01
text text URL URL all or possible
01:00:04
do combine if suddenly
01:00:06
you need both buttons at the same time
01:00:08
send Get Inline Mix buttons Well
01:00:11
let's just call it that and just do it here
01:00:13
check if in value in a loop
01:00:16
which will be transmitted here in this
01:00:19
the dictionary will be like this
01:00:21
sequence Yes as in URL address
01:00:23
there then we do
01:00:25
button c If not, then scb Data
01:00:29
super let's go here to our Emin Prit and
01:00:33
let's do it here
01:00:36
us where our mess an is sent
01:00:39
Any Macaw has a photo, at least it’s simple or
01:00:43
afo there is a parameter that
01:00:45
is also called Mar through which
01:00:48
we send any keyboards or
01:00:50
delete and we transfer ours here
01:00:53
function
01:00:55
so yes
01:00:57
so But and import e and now So
01:01:01
see What does this parameter mean?
01:01:03
if you write it like that with an asterisk, yes that is
01:01:06
just in case you haven't seen this before
01:01:08
Well, at least this is the framework
01:01:10
is commonly used here if
01:01:13
write down this one parameter first
01:01:15
an asterisk and a comma, let's put it this way
01:01:18
automatic front lock
01:01:23
arguments
01:01:25
KST and so on So why are we here?
01:01:29
we do Get butt here in the But parameter
01:01:34
it is necessary to transfer the dictionary we write down
01:01:36
like this, curly braces and now the key U
01:01:40
this dictionary is the first on the first button
01:01:42
we will be told to remove the product AND
01:01:46
now what is the value of the data that
01:01:49
revert back
01:01:53
for when we create a handler for
01:01:56
the meaning will become clear, but for now
01:01:58
we'll write it here like this Delete will do
01:02:02
we will have this underscore F
01:02:04
string that is, We need this data
01:02:07
convey something as a string
01:02:09
in general it means something to us and we are here
01:02:11
we can specify Delete this is what we will do
01:02:12
Let's say this is how we define the prefix
01:02:15
What exactly do we want to delete?
01:02:17
product or change Delete here too
01:02:20
write down, pass on the identifier
01:02:23
product
01:02:26
product so producto dishni That's how we are
01:02:29
we get it and immediately Here separated by commas
01:02:32
since this is a dictionary, let's create a second one
01:02:34
button which will
01:02:37
written
01:02:40
change so change and now here
01:02:44
let's do it like this, essentially the same thing
01:02:48
the only thing here is not Delete, but let’s write
01:02:52
change that is to change
01:02:55
like this and underline product ID like this
01:02:59
what do we have with the dimension now?
01:03:02
us ses is the default tuple 2 then
01:03:06
we have them in one row
01:03:08
great, that is, we are right here now
01:03:10
we can run it all and check it out
01:03:12
let's do it now let's see how
01:03:14
it will look like let's launch the Bot here in
01:03:16
this way and look at these buttons
01:03:19
again we manipulate our
01:03:21
admin and go to the admin panel
01:03:25
click on the assortment Here they are
01:03:27
you can see the delete edit buttons under
01:03:29
every pizza under every product
01:03:31
displayed if we are on it now
01:03:33
Let's press it, you see it constantly shimmers
01:03:36
nothing is happening here or maybe
01:03:38
be a watch like this, that is
01:03:39
signals that there is a callback to us
01:03:41
to the bot went there the line was sent
01:03:44
Delete underline and product ID
01:03:46
but we don't process it in any way
01:03:47
accordingly the user is also
01:03:49
sees that nothing works great and
01:03:52
now it's time to meet
01:03:54
a new type of update called
01:03:56
callback query in order to So it means
01:03:59
now I’ll immediately close the unnecessary online ones
01:04:01
we don't need buttons User Privat we don't need
01:04:04
First of all, let me remind you that we have limited
01:04:08
arrival of update types for So something
01:04:11
Here it’s not like that for me, but it works well
01:04:14
that means there's a problem with the quotes So we
01:04:16
limited the availability of updates in our
01:04:18
bot via allad update accordingly
01:04:20
if Now we will be with you now
01:04:21
work with a new type of update it
01:04:23
you need to write it like this here too
01:04:26
callback quy like this update
01:04:29
it's called, you can write it like this Or I
01:04:32
comment this out
01:04:35
every type of update can be done here
01:04:38
next Thing Here in All updates
01:04:42
don’t pass on this one, let’s put it this way
01:04:44
handwritten design A here
01:04:46
contact the dispatcher directly and
01:04:50
resolve US Update
01:04:53
types and everything like this and those
01:04:56
the updates we use are simple
01:04:58
automatically they will be here
01:05:00
be transmitted and there is also a parameter here
01:05:03
Skip events If suddenly you want
01:05:05
some update to limit but again I
01:05:07
I mean from those that are used
01:05:09
Let's say you want to temporarily block
01:05:12
use here callback quy or
01:05:14
edited mess you can convey the same here
01:05:17
like a string but this is how it will be
01:05:19
work great that is everything
01:05:21
updates we use
01:05:23
will automatically be here and
01:05:24
transmitted so this is firstly secondly
01:05:27
close the App file and go back to
01:05:31
Admin prat Let's create more here
01:05:33
one handler that we will have
01:05:36
be responsible for catching exactly this callback
01:05:38
quy from our Lanova button we will write
01:05:41
the first one is here and we will implement the removal of the product
01:05:44
from the database because changes
01:05:47
will now require more
01:05:49
steps first
01:05:51
so everything's fine let's go
01:05:54
specify a different type
01:05:57
events like that great no commands
01:06:00
we don't need to pass it here
01:06:03
we need to write down the filter we use
01:06:05
exactly the same F filter but not text
01:06:07
nothing but F then D and now here Pay attention
01:06:11
attention This is how we generate
01:06:13
a line with our data which
01:06:15
sent to our bot when clicked
01:06:18
buttons we need to distinguish them
01:06:20
so we write And this is a string
01:06:22
that's why we're here
01:06:25
so it starts with and here we pass that
01:06:29
the string we need
01:06:31
catch starts with Delete
01:06:35
underscores that's it We caught it
01:06:37
now here so here let's add now
01:06:43
Del And now we have caught the event not M
01:06:47
on Nedi's anode, change the parameter itself so that
01:06:51
was
01:06:53
prepare
01:06:55
clarity will be changed now
01:06:58
here the type is not our type anymore
01:07:02
and accordingly we now use from
01:07:05
this type Excellent because in this hdra
01:07:10
Deletion from the database will occur
01:07:12
We also need data here
01:07:15
session and now we are writing
01:07:22
the logic is like this in the callback parameter when
01:07:25
such a request is a callback query
01:07:27
comes to Bota means information
01:07:30
contained here Refer to the parameter
01:07:32
callback then Data and we get this treasured
01:07:36
string but you need to split it somehow Yes
01:07:39
here we have an underscore
01:07:40
Therefore we dot Split break the line
01:07:43
using the delimiter underscore and getting
01:07:46
last element at index -1 That is
01:07:48
it will be Here it is our our ID nickname
01:07:51
great and now aate orm
01:07:54
Del
01:07:56
prod import, transfer the session and
01:08:00
converting product ID into an internal value
01:08:02
which we just received
01:08:04
super and now the next important points
01:08:07
firstly let's go to the last line
01:08:09
Let's take a look at what is written here. In order to
01:08:11
to send Well, in a stake exactly the same
01:08:14
contained How
01:08:16
see the object on which you can apply
01:08:19
goods Wudang will send vve nae nop
01:08:24
message in chat but how to answer like me
01:08:26
spoke directly yes when
01:08:28
click on this button Or watch or
01:08:31
it overflows, that is, more is needed
01:08:33
Let the Telegram server understand
01:08:35
that you and I processed the click on this
01:08:38
online button and this is done using
01:08:40
method an which just has a parameter
01:08:43
object callback
01:08:45
this is not necessary to convey here
01:08:47
In general, anything can be written down simply and
01:08:51
that's all if you pass an additional one here
01:08:53
the text will be displayed when you click on
01:08:56
a button in the form of a small one like this
01:08:58
pop-up text Yes pop-up
01:09:01
notice This is the first and second here
01:09:04
There is also a Show Alert parameter which is
01:09:07
if to which to pass a boolean value
01:09:08
True then an alert will be displayed with
01:09:11
button
01:09:12
Okay, which can only be removed if
01:09:14
click on the button Okay let's say this
01:09:17
The user paid particular attention to the fact that
01:09:19
something happened
01:09:21
real So let's check with us
01:09:24
Let me remind you that the function orm Delete product has already
01:09:27
is specified here in the requests and this is what it is
01:09:30
So this is how we get the session product ID
01:09:33
we get we use
01:09:35
Delete indicate the product where product ID
01:09:38
produc ID se session execute our request and
01:09:43
comit that is, now you and I can
01:09:45
remove products Let's launch and
01:09:48
let's check again
01:09:51
we restore admin rights and click on
01:09:54
any of the buttons delete that is, any of
01:09:57
goods so everything worked goods
01:10:00
deleted again, click on the assortment
01:10:03
check Yes we only have one product
01:10:05
remained great Everything works like that
01:10:08
How
01:10:09
I need the same thing now
01:10:12
basically you and I need to catch
01:10:14
callback quy event button click
01:10:16
if the admin clicks on change product but
01:10:20
now the question is how we will do it
01:10:22
After all, if you look at Yes Tova there is
01:10:24
separately
01:10:25
picture name price description and so on
01:10:27
further That is, this again
01:10:29
a sequence of actions
01:10:30
which should form what
01:10:33
update data which ones should not be updated in
01:10:35
our database
01:10:37
So it's a car again
01:10:40
state machine again, but that's the point
01:10:43
is that Please note that we already have
01:10:45
Yes, there is a machine that forms with us
01:10:47
all the data we need for
01:10:50
adding new
01:10:52
product can be reused
01:10:55
just to avoid adding a new one
01:10:58
product A change an existing one
01:11:00
there is get the data set and this is us
01:11:03
we are implementing it now So we are implementing it now
01:11:07
we modified it a little like this
01:11:08
so that it works for both and for and for
01:11:12
adding and changing how we do it
01:11:14
let's do first of all what I
01:11:16
I'll do it now, we have a class here
01:11:19
which describes our ste and here at
01:11:21
we have this text
01:11:24
notification for the admin so that we have
01:11:27
It’s easier to go back one step
01:11:30
what will we do here I am now this class
01:11:39
moving is done and here it is this class
01:11:42
will be here for him to be just
01:11:44
available for handlers we are now
01:11:46
we'll be here below
01:11:48
write down So now we are with you
01:11:50
we form here here we begin
01:11:55
let's do the next interesting thing
01:11:58
write down
01:11:59
new handler for
01:12:02
processing but in the context of the machine
01:12:04
states, that is, it can be used
01:12:07
not only with messages but literally with
01:12:09
anything with any type of event that
01:12:12
Here generally happens So Events we
01:12:15
here first F
01:12:18
toast cast events press nano button
01:12:22
change
01:12:24
and in ours, let me do it like this
01:12:27
on our Lera which just works
01:12:30
to the command add product
01:12:33
we indicate like this, that is, at the user
01:12:36
there should be no active state in
01:12:39
our very function
01:12:41
obn we first forwarded
01:12:57
let it be possible to do this too though
01:12:59
it’s better to do it with a split here we just
01:13:02
basically cut it out let me redo it
01:13:05
now we'll do the same thing
01:13:08
yes Here
01:13:10
I'll copy it here
01:13:13
let's do it this way it will be much more beautiful
01:13:23
already disney product which user
01:13:25
wants to change we need the media
01:13:27
get this one directly
01:13:28
product from our database in order
01:13:31
so that the user can choose
01:13:34
correct Which fields are already there?
01:13:36
there is a name description price that is
01:13:38
Maybe he has something just the price
01:13:40
will change accordingly we need
01:13:42
We import this product data here
01:13:44
our function orm Get product one
01:13:48
the product that we created in here and
01:13:51
here we call the forward function
01:14:23
this variable will initially be there
01:14:26
Just
01:14:28
Non if no product is available now
01:14:30
changes so product for change is and
01:14:33
Having received this product from the database we
01:14:35
Add product product for change there
01:14:37
assign the object of this product to super
01:14:40
further avit callback Answer we answer
01:14:44
directly to the telegram server so that
01:14:45
he removed the watch from the Lanova button and write
01:14:48
user ait KB message Answer
01:14:50
enter the product name delete
01:14:53
the keyboard that the user had
01:14:56
exactly this
01:14:58
there is add product assortment what
01:15:01
the user could enter text normally
01:15:03
text keyboard displaying to him and
01:15:05
now here in this handler we become in
01:15:09
state that is, we are waiting for input from
01:15:12
user of the new name
01:15:14
accordingly, further we are already like this
01:15:16
let's move see um
01:15:22
Masha T just use the command to add a product
01:15:25
where we also become in the Add state
01:15:28
We don’t touch the product name at all. Not at all.
01:15:30
he is like that and
01:15:32
all that remains is the command cancel and back
01:15:35
we don't touch them either, they remain the same
01:15:38
the most And here's what's next Now we're off
01:15:40
change everything we have next, that is
01:15:43
here is the handler who catches
01:15:45
user status product name then
01:15:47
there is an input of the product name and here
01:15:50
yes text what can we do here After all
01:15:53
this product already has a name What
01:15:56
do if the user doesn't want it
01:15:58
change he wants to get to
01:16:00
prices we do check here first
01:16:03
we don’t touch the state, but we are already with you
01:16:07
it was disassembled, there is such a function
01:16:10
about which it is not possible to transfer options
01:16:13
That is, either or or the user will enter
01:16:16
some text will be able to
01:16:19
we will be working on adding
01:16:22
our product will work if
01:16:24
the user will actually enter some
01:16:26
text or here we can write
01:16:29
differently if the user enters
01:16:31
some special command that
01:16:33
would mean skipping this step and
01:16:35
use the old name of this
01:16:37
product we will do this if the user
01:16:39
will enter a period it will mean leave
01:16:42
old name and of course the orf function
01:16:45
needs to be imported
01:16:47
from so this is us
01:16:50
done and now follow step this
01:16:54
differentiate the behavior of this handler
01:16:56
divide that is or was added
01:16:58
real name of the product or if
01:17:00
the user entered just a dot. So we
01:17:03
here we’ll write it like this if
01:17:07
mess point then we update yes
01:17:12
we will simply update the data in the dictionary
01:17:15
exactly in the dictionary
01:17:19
condition we will name the product there already
01:17:23
indicated otherwise We do everything as
01:17:25
usually update Data name mess T further in
01:17:28
see the description of the product and become
01:17:30
state of waiting for product description AND
01:17:34
we go through the rest in the same way
01:17:35
handlers that we have here for sure
01:17:38
We also change our handler with input
01:17:42
descriptions just add a check If
01:17:45
a dot was entered, then we take the name from
01:17:48
object which we already have goods for
01:17:50
changes If not then from the text
01:17:53
and the same thing continues here
01:17:56
in the price list, if a dot is entered, then we take it
01:18:01
data that was previously otherwise
01:18:04
what was written before in this
01:18:05
handler and the same thing we rule the most
01:18:09
the last handler is where we get
01:18:11
let's write down the images here like this
01:18:14
that is, let's leave everything as it was before
01:18:16
only it’s clear that here and there
01:18:20
old ASHK and the last line in any
01:18:23
case We still need to do
01:18:25
next turn to our
01:18:27
to the Add class
01:18:30
product there we have a variable product F
01:18:33
change and assign it there again Non Yes
01:18:36
to remove from there the product that
01:18:38
there was And here too, correct this one
01:18:41
design That is, if the user
01:18:43
or He uploads a photo or he sends
01:18:46
that's it, that's it. Now let's
01:18:49
everything should be checked already
01:18:52
work
01:18:55
Well, now I’ll take a look at what’s simple here
01:18:58
I'll add an extra one here, but that's okay
01:19:01
launch the Bot and check if it's done
01:19:04
connection manipulation Amin is right
01:19:07
through the group through the team and let's
01:19:09
let's try to change exactly change the product
01:19:12
so here it is written tsa 2 description 2
01:19:14
cost 3 poke for the night change like this
01:19:18
see the product name
01:19:21
SBO Let's try the name right away
01:19:26
let's change it let's leave it like this pizza oh so
01:19:29
how we already have one, poke, enter
01:19:33
description here we enter a point just a point
01:19:36
We want to keep the old description like this
01:19:39
see the price Everything is great
01:19:41
the price slips let it be with us
01:19:43
will cost 2.99 we will give a discount on it
01:19:47
and we’ll also leave the image as it was
01:19:50
again we poke the dot, this means
01:19:53
what do we have here so the product is added needed
01:19:56
just change the text and it’s changed again
01:19:59
look at the assortment we have here
01:20:01
the error means the product was added because
01:20:03
that I was in a hurry here and that means
01:20:07
here in the Trai block you need to do
01:20:09
check Yes, there is only one function here
01:20:11
starts or prod So we are here
01:20:15
replace with the following and make a nested one
01:20:18
checking if the class contains then
01:20:23
then in this case orm update prod like this
01:20:26
now immediately I'll import here let's go
01:20:29
we pass the session session to this function
01:20:32
take it from Add prod CH ID and transfer it
01:20:35
our dictionary date if there n clear
01:20:39
then we just add a new one
01:20:41
product now let me update and make
01:20:44
this is a re-check so here right away
01:20:47
what we just added
01:20:50
delete there again call up the assortment
01:20:54
one product we change it like this 1
01:20:58
the name is like that
01:20:59
further further further description skip
01:21:04
price
01:21:06
299 image No need for this product
01:21:10
added changed look again
01:21:12
assortment so we all have one product
01:21:14
name changed price changed
01:21:16
great and now about here in me
01:21:19
there are two buttons, or rather two HD and back
01:21:24
This is where we have the cancellation handler So where
01:21:27
where where not here above so back
01:21:31
let's pass here he is the cancellation handler here
01:21:33
let's add the following, that is, we If
01:21:36
the user clicked cancel change Yes
01:21:38
exactly the same way it all works we
01:21:40
check if for is useful then we
01:21:43
change prod prod for to so that it is not there
01:21:47
it was like that, in principle, with this you and I
01:21:51
figured it out
01:21:53
Now we will connect the database using SQL
01:21:56
to see how it is
01:21:57
works and so on, especially since it even
01:22:00
It'll just be a lot better on PC.
01:22:02
work as
01:22:03
supports multiple cursors then
01:22:06
there are sessions and so on I will repeat this
01:22:08
all the code will be on Github so
01:22:10
Let's start working directly with
01:22:13
database using SQL because firstly
01:22:16
you need to install the server on a PC like me
01:22:18
and said when when you connect
01:22:20
download your bot somewhere there
01:22:23
Accordingly, we have our own database settings
01:22:26
take any data right there
01:22:29
on the server But if you want Now
01:22:31
test how it will all work out
01:22:32
work it must be done with us
01:22:35
PC and for this court it is SQL
01:22:38
more difficult precisely because of your work than
01:22:40
one file SQL is therefore necessary on
01:22:43
while installing let's say this is the server
01:22:47
directly herself
01:22:51
There is a program. Therefore, there is a reason for Dzhangi
01:22:54
exactly
01:22:55
installation I'll insert it here now A
01:22:58
Next we will now configure it after
01:23:00
it will be shown in this video, let’s set it up now
01:23:03
this whole thing comes after
01:23:05
you install it like this
01:23:08
fill in SQL lorg website, go like this
01:23:14
we climb into Down And now let's go So
01:23:19
users
01:23:21
Linux wine here there are a lot of options
01:23:24
please via deb if Dean is an option
01:23:27
So here we are, here you go
01:23:29
the instructions on macos are also much simpler
01:23:33
please for macos here we poke
01:23:36
download Installer opens like this
01:23:38
website and it is exactly the same as for
01:23:40
Windows since I work on Windows And
01:23:43
most users also
01:23:45
Windows So let's go to Windows and open it
01:23:48
Down Install tab and what do we need here?
01:23:53
let's say here is a general site here and macos
01:23:55
please installers and Windows here is Czech
01:23:59
bit, this is the little thing we need
01:24:01
who is old thirty-two bit although well
01:24:03
unlikely, but nevertheless, here you go
01:24:05
Linux users here are these links for you
01:24:08
will lead back to the same site where
01:24:10
There will be step by step installation instructions
01:24:13
via terminal So what version now
01:24:16
set like this like this from 127 and that’s it
01:24:20
please put liu above
01:24:22
16 Maybe now there after a while
01:24:25
there will be 17 howl here put them or
01:24:27
sixteenth fifteenth from the guide
01:24:29
don't go far from all these versions
01:24:31
are supported for starters after all
01:24:33
Let's bet 161 I'm betting for Windows
01:24:36
64 Bit installer
01:24:40
I download it so we throw it on the desktop
01:24:43
And
01:24:44
let's go So let's run the installer like this
01:24:48
let's go what we have here welcome
01:24:51
Next so Program Files leave everything as it is
01:24:54
Why not Next Now look means
01:24:59
that four components will be installed here
01:25:01
pog SQL Server is basically that
01:25:03
the main thing we need PG Admin 4 is
01:25:06
additionally Visual let's say
01:25:08
db browser type program for SQL In general
01:25:11
Let's put all this further. Now we'll figure it out.
01:25:13
if anything Delete like this next Next like this
01:25:18
Data directory that is where it will be
01:25:19
let's say your tables are stored in general
01:25:23
It suggests in Program Files there is no bad
01:25:25
no place, we won’t store it there with you
01:25:28
I'm sure there's a place on PC somewhere
01:25:30
such a working one let's say so here and
01:25:34
let's create some kind of folder where they will be
01:25:37
this data is stored with
01:25:40
tables and other things like this
01:25:42
let's call her
01:25:44
So
01:25:47
yeah that's it
01:25:51
so we select it ok further as it is
01:25:55
something locally on your PC too
01:25:57
short type here I mean
01:26:00
regarding the password according to the grq standard further
01:26:03
the following works on the port
01:26:06
5432
01:26:09
Next is the locale, that is, I see, well
01:26:12
leave default locale
01:26:15
further Next
01:26:18
so and Next that's it
01:26:21
install and when to install
01:26:23
finished here bu we don’t need it press
01:26:26
sh all And now after installation we launch
01:26:30
a special program that
01:26:31
installed along with the server in order to
01:26:34
so that we can through the interface
01:26:36
interact with our database
01:26:38
data like this on Windows in the start menu
01:26:41
find the SQL version that you installed and
01:26:43
here is PG Admin 4 on some
01:26:46
PG 4 distribution does not install
01:26:49
can be installed separately or as
01:26:51
alternative
01:26:52
db is also a special program for
01:26:55
browsing databases via
01:26:59
interface if during startup you have
01:27:02
an error is displayed here then Click on
01:27:05
config yes, that is, configure and install
01:27:07
the time limit is a little longer in
01:27:12
seconds because the program is enough
01:27:14
heavy and takes a long time to start up
01:27:16
just Tite may not be enough let's say
01:27:20
so after the program firstly immediately
01:27:23
may ask for a password or when clicked
01:27:25
ask the server for that password here
01:27:28
which you entered into the installer, that is
01:27:30
Well, okay, everyone is loading
01:27:34
databases that are here because
01:27:36
this is a system, that is, a court system
01:27:38
database management then here is the date
01:27:40
maybe there's more than one of them coming
01:27:43
standard, don't touch it, we'll do it now
01:27:45
let's create
01:27:46
the new one can do the same thing by the way
01:27:49
via terminal on Windows That's for sure
01:27:52
also here is So here it is SQL Shell
01:27:55
psql on Linux and on Mac is easy to open
01:27:58
terminal and type psql should open
01:28:01
Here
01:28:03
such a thing where you need to connect to
01:28:06
to the server if it is Local Host like ours
01:28:08
here we just skip and click
01:28:12
Enter Database next to which database
01:28:15
data
01:28:17
connect this by default if
01:28:21
which is exactly how we are here now
01:28:23
same
01:28:24
log in and let's look at the Database
01:28:28
pog too if it is She is standard
01:28:30
basic which is automatically exactly that
01:28:32
is always being created That is, you have now
01:28:34
only one here, press Enter
01:28:36
Port confirm standard username
01:28:39
username is also a base pic
01:28:43
always and now user password
01:28:45
enter the password Root Well, the one we are
01:28:47
you entered it yourself, it is not displayed here
01:28:49
typed entered Ender everything And now this
01:28:53
that means we entered Exactly the same here
01:28:57
and now we will do all this in the console
01:29:01
via Clint But let's see it there for
01:29:03
started the first thing you and I need
01:29:05
do this create by logging in under this
01:29:07
main user create new
01:29:10
new user one more for
01:29:11
control of one specific
01:29:13
base
01:29:14
Group RS data right
01:29:20
button
01:29:25
let it be
01:29:27
so anything
01:29:29
thematic so on
01:29:32
the next thing is to create a password for him too
01:29:36
let it be a simple password too
01:29:39
There are no additional points here
01:29:41
we touch the privileges, we poke everything so that
01:29:44
he could do
01:29:50
we skip everything else and move on
01:29:53
Now click on the SQL tab and here is SQL
01:29:56
The request that will be generated is
01:29:59
there is essentially if we want the same thing now
01:30:01
The best thing to do is through this client here
01:30:04
you need to write this to the console
01:30:06
SQL query and everything will be the same, well
01:30:09
in the meantime we press on
01:30:11
Save That's it for us, he's a bot
01:30:15
created
01:30:17
special user through whom
01:30:19
we will work with a database that
01:30:22
now for him
01:30:27
let's create, that is, a control system
01:30:29
version database management system
01:30:32
data can be served simultaneously
01:30:35
many databases So we have her too
01:30:38
let's call it the same as T Yes, so as not to forget
01:30:42
What's what?
01:30:44
further
01:30:50
here we select the managing user
01:30:53
firstly the basic user is he
01:30:55
generally rules everyone at once And now we
01:30:59
indicate the bot as additional
01:31:02
administrator of the owner of this new
01:31:04
the database that we will now create
01:31:07
tact and the name of the bot next
01:31:10
Definition we must go here
01:31:12
ding ut F8 should be if different
01:31:14
Change the dropdown here
01:31:16
nothing else listed here
01:31:19
no need to touch
01:31:20
So
01:31:22
Onet everything in principle and now let’s move on
01:31:26
to the SQL tab and we see
01:31:28
again there is a SQL Query that will create
01:31:31
this database that is now here in
01:31:33
terminal if you are using the terminal suddenly
01:31:36
decided to enter something like this Request everything So
01:31:39
I'll close this one, it's not needed Let's do everything
01:31:41
equally through the program and click Save
01:31:45
We've all created a new base
01:31:47
data home - this is from a lesson on Django This
01:31:50
I don't remember what the bot did here
01:31:56
the diagram then opens drop-down
01:32:00
menu and here they are, there is a table
01:32:04
T here is empty now but then when
01:32:08
Now the system will create these tables You
01:32:11
right-click on the table and there
01:32:14
you can view it, that is, of course
01:32:16
that here through this program you can
01:32:19
requests write view here
01:32:20
for example I'm there
01:32:23
where was the online furniture store?
01:32:27
So pish means So it means like this
01:32:33
tables like this and for example where A
01:32:38
Well, here we have a product sign for it
01:32:43
right click and
01:32:45
here View Edit Data All Rolls for example
01:32:49
here is the request, here is the result, that is, all this
01:32:52
here I am already her now
01:32:54
I'm closing. Don't pay attention to this.
01:32:56
window we're done
01:32:58
created and now we’re climbing back to ours
01:33:01
connect the bot to this database
01:33:05
data code of the requests themselves from the orm file
01:33:09
quy we don’t touch it at all it’s the same
01:33:11
for any base
01:33:13
data is the next thing we need
01:33:16
do this We open the fa so the package and
01:33:20
open fa
01:33:22
that is, we just need to go here
01:33:25
transfer here to Create as Engine now
01:33:28
different database URL and engine
01:33:31
do it here in the file then so I
01:33:35
I have prepared this one so far
01:33:38
stub I'll copy it from here right away Here
01:33:40
I’ll post it because the NV file is in
01:33:44
It’s clear that it’s not uploaded to github
01:33:46
So where is the File Engine?
01:33:50
gone, so I'll leave this sample here
01:33:53
Here
01:33:56
I'll write this down right now
01:34:04
duplicate
01:34:20
koto for pog SQL pog SQL plus library
01:34:25
which we use we already use it
01:34:27
installed at the beginning of this video asing PG
01:34:30
then colon two not three but two two
01:34:34
slash and then indicate like this
01:34:37
script login colon Password next
01:34:42
symbol Dog Aka Add Local Host like this
01:34:45
how is it, well, let's say it like this, that is
01:34:48
where is this database located?
01:34:50
it works on our computer, we have this
01:34:53
Local Host or you can write here
01:34:55
directly IP address
01:34:58
127.0 to1 colon port and base name
01:35:02
data from us, we did this and login and
01:35:05
password
01:35:06
bobot to make it easier now
01:35:09
It’s clear that on a real server
01:35:11
already write complex login and password further
01:35:15
Local Host leave the port leave and
01:35:18
database name is also a bot all this
01:35:21
enough This is the URL address of our database
01:35:25
super data File NV We are closing everything
01:35:29
now here in the URL we just change the name
01:35:33
variables where we store this URL
01:35:35
osg 10 address in db URL that's it and that's it
01:35:41
this is where the whole thing ended, we
01:35:44
connected to our pog SQL bot Let's
01:35:47
run and check this SQL file
01:35:51
because suddenly you want through
01:35:53
sqlite work Well, basically if
01:35:56
Delete it Well, it will be created again If
01:35:59
you again Connect the SQL engine So
01:36:02
launch the Bot and see What
01:36:05
How can we generate everything again?
01:36:08
SQL queries are all great That is, we
01:36:10
connected, no errors, that's all
01:36:12
ok, we have created tables there
01:36:16
great I'm right here now by the way Well
01:36:19
I will delete yes To make it clear that
01:36:22
We definitely don’t work with sqlite, so I delete it
01:36:24
the sqlite database itself and now
01:36:27
Let's work more with our Bot, let's say so
01:36:29
I'll do the last one
01:36:31
test we write him the Admin command in
01:36:35
group and go to our admin panel like this
01:36:39
let's clear all the history so that it doesn't
01:36:41
got in the way like that
01:36:42
clear
01:36:44
delete AND
01:36:46
now Request
01:36:48
menu here's the menu, that is, it's empty
01:36:51
there is nothing Let's enter the command like this
01:36:53
Admin and let's load the goods there, let's go
01:37:00
let's add Pizza
01:37:02
One description
01:37:05
one price and we'll drop it now
01:37:10
picture So come here, click on
01:37:15
send like this product added no errors
01:37:18
great poke at the assortment
01:37:21
look at the products
01:37:24
unloaded, I'll add another one like this
01:37:28
loaded a total of four pieces, click on
01:37:30
assortment 1 2 3 4 delete everything like this
01:37:34
change this in the admin panel yes that is
01:37:36
these buttons Let's check the others
01:37:39
once again, no need to delete everything, so the goods
01:37:41
deleted everything is displayed again on
01:37:44
assortment 1 2 3 and this last one
01:37:48
let's change now change
01:37:52
Name
01:37:54
we'll leave the description, we'll also leave it, we'll change it
01:37:57
he had a price, let's do it
01:38:01
450 and leave the image too
01:38:05
super assortment again latest tests
01:38:08
now they are like that Yes, so 450 is super and now
01:38:12
Let's try to cancel
01:38:15
let's make changes like this
01:38:19
pizza let's go dot let's go
01:38:23
Now let's see if the command works
01:38:27
back click back you are back to
01:38:30
previous step and enter a description
01:38:34
again new description so price
01:38:40
let's leave it at that
01:38:43
leave the product added changed
01:38:47
assortment team back working and
01:38:50
Now let's check the last command
01:38:52
we'll skip the cancellations
01:38:56
skip enter price
01:38:59
hundreds of goods and at this stage we write
01:39:03
command cancel What we have to do there
01:39:06
canceled everything works
01:39:08
Okay, as I said, the code from this video
01:39:11
it will be in github we had a lesson
01:39:15
7 with you was the Python Hub Studio channel before
01:39:18
next videos
01:39:20
bye S

Description:

В этом видео, по созданию Телеграм бота на python с aiogram 3, будем работать асинхронно с базой данных postgresql и sqlite через ORM систему SqlAlchemy, познакомимся с middleware слоями в aiogram 3, а также с Inline кнопками и клавиатурами и событием callback query. 00:00 Обзор кода Телеграм бота на aiogram 3 с прошлого видео 02:40 Middleware слои в aiogram 3 14:53 Работа с базой данных. Установка sqlalchemy, asyncpg и aiosqlite 17:51 Создание / описание моделей (таблиц) в sqlalchemy 26:30 Создание асинхронного engine и менеджера сессий sqlalchemy 35:56 Передача сессий orm sqlalchemy через middleware слой в хендлер aiogram бота 39:02 Добавление товара в таблицу базы данных 47:29 Удаление товара из таблицы 53:32 Отправка изображений ботом 56:29 Инлайн клавиатуры и кнопки в aiogram 3 01:04:14 Событие Callback Query 01:10:06 Изменение товара в БД. Модифицируем FSM на добавление/изменение товара 01:23:06 Установка PostgreSQL сервера на ПК 01:26:32 Создание базы данных в PostgreSQL и создание нового пользователя 01:33:04 Подключение бота на работу с PostgreSQL 01:36:06 Финальные тесты Поддержать канал: На канале доступна функция Спонсорство с дополнительными бонусами. Присоединиться: https://www.youtube.com/c/PythonHubStudio/join А также кнопка Суперспасибо под видео (отображается не во всех странах). Документация API Telegram: https://core.telegram.org/api Документация aiogram: https://docs.aiogram.dev/en/latest/ Код из видео: https://github.com/PythonHubStudio/aiogram-3-course-telegram-bot Этот плейлист: https://www.youtube.com/playlist?list=PLNi5HdK6QEmWLtb8gh8pwcFUJCAabqZh_ Настройка VS Code как у меня: https://www.youtube.com/watch?v=e15PvHRHB_w Курс по python 7 часов: https://www.youtube.com/watch?v=5g-MHZ0MzZY Видео про асинхронность: https://www.youtube.com/watch?v=_4QY1nGFRY8 Курс по Django 15 часов: https://www.youtube.com/playlist?list=PLNi5HdK6QEmWNqncVoUZtj1QDC2VV0wI6 Курс HTML / CSS: https://www.youtube.com/watch?v=Bmtu5eNnjK8 Не забудьте подписаться и включить оповещения, чтоб не пропустить новые выпуски!

Preparing download options

popular icon
Popular
hd icon
HD video
audio icon
Only sound
total icon
All
* — If the video is playing in a new tab, go to it, then right-click on the video and select "Save video as..."
** — Link intended for online playback in specialized players

Questions about downloading video

mobile menu iconHow can I download "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery" video?mobile menu icon

  • http://unidownloader.com/ website is the best way to download a video or a separate audio track if you want to do without installing programs and extensions.

  • The UDL Helper extension is a convenient button that is seamlessly integrated into YouTube, Instagram and OK.ru sites for fast content download.

  • UDL Client program (for Windows) is the most powerful solution that supports more than 900 websites, social networks and video hosting sites, as well as any video quality that is available in the source.

  • UDL Lite is a really convenient way to access a website from your mobile device. With its help, you can easily download videos directly to your smartphone.

mobile menu iconWhich format of "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery" video should I choose?mobile menu icon

  • The best quality formats are FullHD (1080p), 2K (1440p), 4K (2160p) and 8K (4320p). The higher the resolution of your screen, the higher the video quality should be. However, there are other factors to consider: download speed, amount of free space, and device performance during playback.

mobile menu iconWhy does my computer freeze when loading a "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery" video?mobile menu icon

  • The browser/computer should not freeze completely! If this happens, please report it with a link to the video. Sometimes videos cannot be downloaded directly in a suitable format, so we have added the ability to convert the file to the desired format. In some cases, this process may actively use computer resources.

mobile menu iconHow can I download "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery" video to my phone?mobile menu icon

  • You can download a video to your smartphone using the website or the PWA application UDL Lite. It is also possible to send a download link via QR code using the UDL Helper extension.

mobile menu iconHow can I download an audio track (music) to MP3 "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery"?mobile menu icon

  • The most convenient way is to use the UDL Client program, which supports converting video to MP3 format. In some cases, MP3 can also be downloaded through the UDL Helper extension.

mobile menu iconHow can I save a frame from a video "Асинхронная SqlAlchemy | База Данных в Telegram боте на aiogram 3 #7 Middleware слои, CallbackQuery"?mobile menu icon

  • This feature is available in the UDL Helper extension. Make sure that "Show the video snapshot button" is checked in the settings. A camera icon should appear in the lower right corner of the player to the left of the "Settings" icon. When you click on it, the current frame from the video will be saved to your computer in JPEG format.

mobile menu iconWhat's the price of all this stuff?mobile menu icon

  • It costs nothing. Our services are absolutely free for all users. There are no PRO subscriptions, no restrictions on the number or maximum length of downloaded videos.