📺 Develpreneur YouTube Episode

Video + transcript

SQL Sync Final Episode

2022-12-29 •Youtube

Detailed Notes

Focus for this episode: We wrap up our data synchronization issues and the final changes needed to make this whole application work. Now there is an application we can use to synchronize and quickly spin up development databases.

This tutorial series walks through the creation of a database synchronization tool in Python. It continues our Python and SQL Tutorials with a useful application that provides a deeper look at SQL structures and commands.

Repository For Code: git clone [email protected]:rbroadhead/dbsync.git

Transcript Text
foreign
[Music]
well hello and welcome back we are
finally getting to the end of our
database sync and basically I was
walking through a lot of troubleshooting
the last couple episodes really came
down to
one or two changes that I want to talk
through to sort of get us over the hump
uh as it were so the first thing that we
were running into if I can
find the right reference show
uh here we go referential load
so if you remember or you can look back
to the prior a couple of episodes one of
the things we're doing is we're going
through and we
we first pull all the data for the
tables that don't have any references so
we just know and those are based on our
number of rows either if it's set to
zero it's just going to pull everything
otherwise it'll be you know if we set it
to 100 it's going to it's only going to
pull 100 rows out of that table
now when we go to tables that have
references to other tables it's not that
clean
and so what we're doing is we're saying
let's get all the data for the tables we
know the ones where we have like you
know X number of rows let's get that
stuff pulled over and then we're going
to go through and we're going to where
we don't have a table loaded
if something references it then we're
going to build the data based on the
primary Keys within that table
now the trick about that is we can have
a table reference actually three or four
other tables
so we were building this thing
that was called imported tables
and what we weren't doing was checking
it quite enough so we're running in a
couple of situations where
two tables would reference the same
table
and when the first one came through it
was awesome when the second one came
through
it wasn't first checking whether that
table had been imported and it was
causing some issues because technically
we would have gotten and we did we got
all of the correct rows the first time
through
because what we do is we would build if
you remember we would build that query
based on all of the tables that were
referenced
and then that's how we pull the data in
so it was easy for us to you know catch
some have some extra slip through so the
simplest thing to do that is I just say
hey
since we keep we use referential load to
load it first thing I did I said hey if
the table that we're going to load is
already in imported tables then we just
kick imported tables back out we're done
we don't do anything because we're
technically we're done
so we that allows us to not double enter
a table because we were getting it
loaded properly we're getting it
populated
for example somewhere down here we're
going to see where yeah
we're appending
and we're good so we are saying hey this
thing got you know got built one way or
another or here we can just do a
straight load of the table data and
we're still we're making sure that we
get that table in there if we get it
into imported tables twice we really
don't care if it's in that array twice
what we don't want to do is if it's
there once we don't want to checking you
know we don't want to try to load again
so putting this
check up here
should and did in all the cases I was
running through did fix that now another
thing that I was running into which is
really a change in how you uh it's to
address something that should not happen
one of the things I ran into that we
talked about well that got me wondering
about how we were doing enumerated types
back several episodes
one of the things we're running into is
that enumerated types weren't coming
across properly we're getting things
where it wasn't it was telling us
there's basically a a size constraint
for a value that we're putting into an
enumerated row so an enumerated values
could be things so like we could do like
enum
and let's say it's uh
and this is it's not going to look
exactly like that but let's say we had
an enome that was like grape apple
Orange
and so that would mean that in that
column we should see grape apple or
orange
but I've run into some situations where
there would be for example an empty
string
or
we had some sort of an a new an enum
where
like let's say we had uh
some large let's say some long name
and then later we came back and said no
we don't want that what we really want
is just these three well the problem is
it not necessarily it's not necessarily
going to go back and fix that so you may
still have even though you changed the
enum
when you change the enumerator type it
is not necessarily going to like it's
not going to like cause a trigger or
something that's going to break the data
and say Hey you have to remove the
fields that have that value so there are
ways to get invalid
enum values into data and that was
causing some issues and so the easiest
way to fix that is to cheat and so
that's where we go back and use our
where is it uh I'll find one here
we use our try and accept
so basically what we're going to do
there is say hey I'm going to try to
execute this
but I'm not going to bother if it
doesn't I also ran into this in a couple
of there's some odd
combinations of a table SQL that was
getting pulled across I couldn't figure
out how they built it in the first place
because it was technically
illegal like if I just take this the
pure SQL it does not like it
so in those cases what I do is I just
say hey if I can't generate it if I get
an exception trying to execute it
instead of bailing out on the script
entirely what I'm going to do is I'm
just going to print whatever it was I
was trying to run and then I'm just
going to continue on
so what I would end up getting somewhere
back here maybe is stuff like uh let's
see
if I can find one down here but I think
I got them all clean so it's probably
not going to show up anymore
but I would get
yeah
unfortunately I didn't steal that
oh here like here's one
so I think it didn't like this for some
reason
and
it just kicked this out
I'm not sure why I did but uh so for
example it didn't run this one so
whatever the enume was
uh oh like here they had this
and I believe this is source and this is
destination so destination had this
thing that didn't value that was some
weird value that we had in there and it
said hey I'm not going to allow that so
when we tried to alter it for some
reason it didn't do it maybe the trigger
actually kicked in in this case or it
could have been the I don't know the
null wouldn't have been a problem but
for some reason it didn't like it so if
I wanted I could I can see that on my
output and I can go in and try to
manually fix that if I need to
um you know it depends sometimes that's
going to be an issue sometimes it's not
but it does allow us to for the most
part then push everything across and
then we can always go back and do the
fixes
and that allows us now to do it based on
uh max number of rows as opposed to just
having to do everything and sort of Slam
at home by you know shutting off
triggers and constraints
and in so doing we now have a script
that will run through
and we can do whatever we need to with
it as far as tables or triggers or store
procedures or functions and
let's see so we don't really need these
notes anymore
and so we have is we've got our little
feature flag thing so if we come in
we can pick whichever values we want to
do which is
tables columns indexes rows row data
synchronized procedures we've got a
couple we missed I think we missed so we
need that Dash f for our functions
so we'll do that
uh let's see so t c
d
I
p
r
ows F functions and TR would be whatever
TR was what was TR is oh triggers
let's do this
now we have our
are sort of our documentation of sorts
and it's going to go in and do these and
it does them in uh a bit of an order
you know we do have a logical order to
it and it's going to come through for
each of the or actually it goes down
here we're going to come through here
and depending on what we have
we're going to do these for each of our
list of databases within our
settings.py file we went ahead and
pulled that in so we're going to we
pulled our source our Target our
databases so we've got a database list
here
and it's just going to be a list of
names and so you do need that database
to exist so you can't just
you know say I've got a Dev database you
can't just push that when it's not there
you're going to have to actually do you
know create database depth so it does
assume that much it assumes at least
that you've gone in and created your
database
but once you've got it
it's going to fly through and you can
you know play around with it I would
definitely not create a database you
know somewhere that you are worried
about it right now and it's put it on a
local maybe initially and use it to see
if the database the data is coming
across properly connect to it maybe if
you've got unit tests or something to
run against it that will help
and once you've done that then you've
got you know this thing you can plug it
into however you want to
all of these functions are pretty
straight moderately straightforward like
I said we've got the uh the tries that
we've added now so it's a little more
likely to go through it's not going to
just bail out like it did before I have
adjusted a little bit some of the
sum of the output that is here so you're
not going to see quite as much
um basically just because it was a lot
to see you see we've got a lot of like
debug related stuff that is still in
there
but after all of that uh debugging and
walking through and coding and things
like that it turned out that it was
actually a little bit of a an invalid
database I was pulling across
and that was what was really you know
biting me is that I had something in a
state that it should not have gotten to
and it's in case basically the
referential integrity was not exactly
where it was supposed to be but if you
do this you should be able to get it as
long as you make sure you know that you
should be able to keep your referential
integrity but that's again make sure
that you're doing things like grabbing
your uh your eye your indexes your
triggers
and pull those things across and you
should be in good shape if you want a
like a development version a very quick
and clean database is you can probably
get away with just if you just do tables
columns
and indexes depends on whether or not
you know if you've got functions or
procedures so you could come in and do
like if you wanted to do tables so do
like a dash T Dash C
uh columns indexes Dash I then you could
build out a
sort of like a development a clean or
empty development database pretty quick
if you needed to do your procedures and
your functions add your dash P enter
Dash f
and then you're you've got a pretty in
pretty good shape at that point
so what we've got is something that
allows you to get in there quick make a
database now we actually allow you to
push data into it so it's not just a
shell
and you've got a pretty good example of
a lot of python to work with here as
well not to mention we got pretty deep
into
the world of
um let me go back over here uh we did so
we got pretty deep into especially the
information schema in MySQL so there's a
lot of stuff here if you're ever curious
about how to find
tables or indexes or columns or values
or all that kind of stuff that's the the
metadata this will give you a really
good start you can jump into any one of
the the functions and your pro you know
like say function itself missing
functions I'm going to be able to see
right here that this is roughly how I
can get a list of functions
obviously you know you may there's some
things in here like we've got our
schemas already defined you may get more
than you wanted but you do a select star
and you can start working your way
through it and get down to the specific
query that you need for your information
this has been updated in Version Control
so if you check the links you'll be able
to get the latest you can play around
with it you will have to set up your
settings file you can see where we did
that what it looked like initially and
how we just moved stuff over you'll also
be able to see it if you look up here
uh when it does a connect somewhere in
here
uh oh maybe not let's see
oh so I go right in because I give it
the config and
if I go to here
where is I think I've already just yeah
so I'm just pulling it straight in
because I've already set up most of the
config so you can see that in examples
you can also see that
you need to see it on the code or take a
look back at a couple tutorials early on
we set that up so you can see what needs
to be done to configure your source and
your target database make sure you do
not confuse the two because that can
cause you all sorts of not fun things to
happen
that being said
we can finally wrap this one up so we
will continue throwing out uh various
tutorials and stuff like that I think
this gives us a good hopefully you've
had a really good uh sir crash course
into SQL particularly my Sequel and
python using those building some scripts
and finding kind of you know useful
little application maybe that you can
build and now you have something that
you can you can build on top of this and
see where your see where your skills
take you
that being said we'll let you get back
to it so go out there and have yourself
a great day a great week and we will
talk to you next time
[Music]
Transcript Segments
0.42

foreign

18.89

[Music]

27.24

well hello and welcome back we are

29.76

finally getting to the end of our

32.22

database sync and basically I was

35.34

walking through a lot of troubleshooting

36.719

the last couple episodes really came

39.3

down to

40.739

one or two changes that I want to talk

42.719

through to sort of get us over the hump

45.6

uh as it were so the first thing that we

48.36

were running into if I can

53.46

find the right reference show

59.82

uh here we go referential load

62.64

so if you remember or you can look back

65.4

to the prior a couple of episodes one of

67.68

the things we're doing is we're going

68.7

through and we

70.02

we first pull all the data for the

72.06

tables that don't have any references so

73.92

we just know and those are based on our

76.439

number of rows either if it's set to

79.26

zero it's just going to pull everything

81

otherwise it'll be you know if we set it

83.7

to 100 it's going to it's only going to

85.74

pull 100 rows out of that table

88.38

now when we go to tables that have

91.799

references to other tables it's not that

94.38

clean

95.579

and so what we're doing is we're saying

97.5

let's get all the data for the tables we

99.54

know the ones where we have like you

101.34

know X number of rows let's get that

102.78

stuff pulled over and then we're going

105.42

to go through and we're going to where

108

we don't have a table loaded

111.6

if something references it then we're

113.579

going to build the data based on the

116.46

primary Keys within that table

119.939

now the trick about that is we can have

122.399

a table reference actually three or four

125.04

other tables

126.78

so we were building this thing

129.899

that was called imported tables

133.8

and what we weren't doing was checking

135.9

it quite enough so we're running in a

138.18

couple of situations where

140.52

two tables would reference the same

142.98

table

143.879

and when the first one came through it

146.28

was awesome when the second one came

148.319

through

149.16

it wasn't first checking whether that

152.099

table had been imported and it was

154.5

causing some issues because technically

156.18

we would have gotten and we did we got

157.98

all of the correct rows the first time

160.44

through

161.4

because what we do is we would build if

163.44

you remember we would build that query

165.14

based on all of the tables that were

168.599

referenced

170.099

and then that's how we pull the data in

173.22

so it was easy for us to you know catch

175.5

some have some extra slip through so the

178.44

simplest thing to do that is I just say

179.94

hey

180.72

since we keep we use referential load to

183.54

load it first thing I did I said hey if

186.599

the table that we're going to load is

188.28

already in imported tables then we just

191.28

kick imported tables back out we're done

193.019

we don't do anything because we're

194.58

technically we're done

196.26

so we that allows us to not double enter

200.76

a table because we were getting it

203.519

loaded properly we're getting it

205.2

populated

206.519

for example somewhere down here we're

209.099

going to see where yeah

211.019

we're appending

213.3

and we're good so we are saying hey this

216.36

thing got you know got built one way or

218.159

another or here we can just do a

220.44

straight load of the table data and

222.48

we're still we're making sure that we

224.22

get that table in there if we get it

226.56

into imported tables twice we really

228.36

don't care if it's in that array twice

230.58

what we don't want to do is if it's

232.86

there once we don't want to checking you

236.28

know we don't want to try to load again

237.48

so putting this

240.84

check up here

243.42

should and did in all the cases I was

245.76

running through did fix that now another

248.519

thing that I was running into which is

254.459

really a change in how you uh it's to

259.019

address something that should not happen

261.6

one of the things I ran into that we

263.58

talked about well that got me wondering

266.22

about how we were doing enumerated types

269.36

back several episodes

272.28

one of the things we're running into is

273.96

that enumerated types weren't coming

275.34

across properly we're getting things

276.78

where it wasn't it was telling us

278.52

there's basically a a size constraint

281.46

for a value that we're putting into an

283.5

enumerated row so an enumerated values

286.32

could be things so like we could do like

288.479

enum

289.86

and let's say it's uh

294.54

and this is it's not going to look

296.04

exactly like that but let's say we had

297.24

an enome that was like grape apple

300.72

Orange

302.94

and so that would mean that in that

304.8

column we should see grape apple or

308.699

orange

309.78

but I've run into some situations where

312.84

there would be for example an empty

314.94

string

316.56

or

318

we had some sort of an a new an enum

320.94

where

322.56

like let's say we had uh

326.479

some large let's say some long name

330.72

and then later we came back and said no

332.699

we don't want that what we really want

338.039

is just these three well the problem is

340.259

it not necessarily it's not necessarily

342.84

going to go back and fix that so you may

344.82

still have even though you changed the

346.5

enum

347.479

when you change the enumerator type it

350.039

is not necessarily going to like it's

351.479

not going to like cause a trigger or

352.86

something that's going to break the data

354.36

and say Hey you have to remove the

356.699

fields that have that value so there are

359.28

ways to get invalid

361.68

enum values into data and that was

365.759

causing some issues and so the easiest

369.06

way to fix that is to cheat and so

372.78

that's where we go back and use our

375.56

where is it uh I'll find one here

379.02

we use our try and accept

381.66

so basically what we're going to do

382.68

there is say hey I'm going to try to

385.68

execute this

387.24

but I'm not going to bother if it

389.46

doesn't I also ran into this in a couple

392.1

of there's some odd

394.52

combinations of a table SQL that was

398.28

getting pulled across I couldn't figure

399.479

out how they built it in the first place

400.86

because it was technically

403.62

illegal like if I just take this the

406.319

pure SQL it does not like it

409.139

so in those cases what I do is I just

412.319

say hey if I can't generate it if I get

414.66

an exception trying to execute it

417.12

instead of bailing out on the script

419.1

entirely what I'm going to do is I'm

421.62

just going to print whatever it was I

423.06

was trying to run and then I'm just

425.34

going to continue on

426.72

so what I would end up getting somewhere

429.36

back here maybe is stuff like uh let's

432.3

see

434.16

if I can find one down here but I think

436.62

I got them all clean so it's probably

438.06

not going to show up anymore

439.919

but I would get

442.62

yeah

443.78

unfortunately I didn't steal that

447.24

oh here like here's one

450.24

so I think it didn't like this for some

452.16

reason

453.84

and

455.58

it just kicked this out

460.199

I'm not sure why I did but uh so for

463.02

example it didn't run this one so

465

whatever the enume was

467.34

uh oh like here they had this

472.199

and I believe this is source and this is

474.419

destination so destination had this

476.16

thing that didn't value that was some

478.02

weird value that we had in there and it

481.5

said hey I'm not going to allow that so

483.12

when we tried to alter it for some

484.44

reason it didn't do it maybe the trigger

486.12

actually kicked in in this case or it

488.28

could have been the I don't know the

490.02

null wouldn't have been a problem but

492.06

for some reason it didn't like it so if

493.86

I wanted I could I can see that on my

496.44

output and I can go in and try to

498.06

manually fix that if I need to

501.419

um you know it depends sometimes that's

502.86

going to be an issue sometimes it's not

504.56

but it does allow us to for the most

507.539

part then push everything across and

510.96

then we can always go back and do the

512.159

fixes

513.539

and that allows us now to do it based on

516.38

uh max number of rows as opposed to just

520.38

having to do everything and sort of Slam

523.02

at home by you know shutting off

524.339

triggers and constraints

526.32

and in so doing we now have a script

530.64

that will run through

533.399

and we can do whatever we need to with

536.1

it as far as tables or triggers or store

539.64

procedures or functions and

545.22

let's see so we don't really need these

547.08

notes anymore

549.66

and so we have is we've got our little

551.339

feature flag thing so if we come in

554.279

we can pick whichever values we want to

557.76

do which is

560.459

tables columns indexes rows row data

564.26

synchronized procedures we've got a

566.279

couple we missed I think we missed so we

569.04

need that Dash f for our functions

574.5

so we'll do that

576.54

uh let's see so t c

580.62

d

582.54

I

584.58

p

586.38

r

588.48

ows F functions and TR would be whatever

594.3

TR was what was TR is oh triggers

600.36

let's do this

604.44

now we have our

607.98

are sort of our documentation of sorts

612.66

and it's going to go in and do these and

614.339

it does them in uh a bit of an order

618.54

you know we do have a logical order to

620.459

it and it's going to come through for

622.74

each of the or actually it goes down

624.3

here we're going to come through here

625.86

and depending on what we have

628.14

we're going to do these for each of our

630

list of databases within our

633.14

settings.py file we went ahead and

635.04

pulled that in so we're going to we

636.779

pulled our source our Target our

639.24

databases so we've got a database list

642.36

here

643.74

and it's just going to be a list of

645

names and so you do need that database

647.399

to exist so you can't just

649.74

you know say I've got a Dev database you

652.5

can't just push that when it's not there

655.019

you're going to have to actually do you

657

know create database depth so it does

658.8

assume that much it assumes at least

660.48

that you've gone in and created your

662.7

database

664.56

but once you've got it

666.24

it's going to fly through and you can

668.519

you know play around with it I would

670.88

definitely not create a database you

675.779

know somewhere that you are worried

677.16

about it right now and it's put it on a

679.019

local maybe initially and use it to see

682.56

if the database the data is coming

684.48

across properly connect to it maybe if

687.24

you've got unit tests or something to

688.56

run against it that will help

692.279

and once you've done that then you've

694.74

got you know this thing you can plug it

696.72

into however you want to

698.42

all of these functions are pretty

700.5

straight moderately straightforward like

702.779

I said we've got the uh the tries that

705.3

we've added now so it's a little more

706.92

likely to go through it's not going to

708.72

just bail out like it did before I have

711.779

adjusted a little bit some of the

716.22

sum of the output that is here so you're

719.579

not going to see quite as much

722.82

um basically just because it was a lot

724.26

to see you see we've got a lot of like

726.12

debug related stuff that is still in

728.16

there

728.94

but after all of that uh debugging and

732.12

walking through and coding and things

733.8

like that it turned out that it was

735.899

actually a little bit of a an invalid

739.32

database I was pulling across

741.48

and that was what was really you know

743.7

biting me is that I had something in a

745.62

state that it should not have gotten to

749.279

and it's in case basically the

752.22

referential integrity was not exactly

754.26

where it was supposed to be but if you

756.18

do this you should be able to get it as

757.68

long as you make sure you know that you

758.94

should be able to keep your referential

760.5

integrity but that's again make sure

763.139

that you're doing things like grabbing

766.139

your uh your eye your indexes your

769.079

triggers

770.279

and pull those things across and you

773.279

should be in good shape if you want a

777.12

like a development version a very quick

779.519

and clean database is you can probably

781.26

get away with just if you just do tables

784.38

columns

786.24

and indexes depends on whether or not

788.519

you know if you've got functions or

790.88

procedures so you could come in and do

796.32

like if you wanted to do tables so do

799.139

like a dash T Dash C

802.1

uh columns indexes Dash I then you could

805.98

build out a

809.1

sort of like a development a clean or

811.139

empty development database pretty quick

813.12

if you needed to do your procedures and

814.68

your functions add your dash P enter

816.779

Dash f

818.22

and then you're you've got a pretty in

821.7

pretty good shape at that point

823.38

so what we've got is something that

825.72

allows you to get in there quick make a

827.279

database now we actually allow you to

829.139

push data into it so it's not just a

831.54

shell

832.68

and you've got a pretty good example of

835.98

a lot of python to work with here as

837.6

well not to mention we got pretty deep

839.519

into

840.72

the world of

842.7

um let me go back over here uh we did so

845.04

we got pretty deep into especially the

846.779

information schema in MySQL so there's a

849.839

lot of stuff here if you're ever curious

852.24

about how to find

854.42

tables or indexes or columns or values

858

or all that kind of stuff that's the the

860.1

metadata this will give you a really

863.16

good start you can jump into any one of

865.079

the the functions and your pro you know

867.48

like say function itself missing

869.519

functions I'm going to be able to see

871.38

right here that this is roughly how I

873.6

can get a list of functions

875.639

obviously you know you may there's some

878.579

things in here like we've got our

879.6

schemas already defined you may get more

881.76

than you wanted but you do a select star

884.88

and you can start working your way

886.56

through it and get down to the specific

889.32

query that you need for your information

893.1

this has been updated in Version Control

895.74

so if you check the links you'll be able

897.36

to get the latest you can play around

899.1

with it you will have to set up your

900.899

settings file you can see where we did

903.48

that what it looked like initially and

905.399

how we just moved stuff over you'll also

908.04

be able to see it if you look up here

911.66

uh when it does a connect somewhere in

914.699

here

918.38

uh oh maybe not let's see

925.68

oh so I go right in because I give it

927.6

the config and

930.48

if I go to here

933.899

where is I think I've already just yeah

935.88

so I'm just pulling it straight in

938.399

because I've already set up most of the

939.959

config so you can see that in examples

942.899

you can also see that

944.6

you need to see it on the code or take a

947.459

look back at a couple tutorials early on

949.86

we set that up so you can see what needs

951.6

to be done to configure your source and

953.519

your target database make sure you do

955.98

not confuse the two because that can

957.959

cause you all sorts of not fun things to

961.32

happen

962.459

that being said

964.38

we can finally wrap this one up so we

967.079

will continue throwing out uh various

969.899

tutorials and stuff like that I think

971.459

this gives us a good hopefully you've

973.74

had a really good uh sir crash course

976.38

into SQL particularly my Sequel and

980.04

python using those building some scripts

983.279

and finding kind of you know useful

984.959

little application maybe that you can

986.339

build and now you have something that

988.68

you can you can build on top of this and

992.279

see where your see where your skills

994.68

take you

995.519

that being said we'll let you get back

997.079

to it so go out there and have yourself

998.459

a great day a great week and we will

1001.279

talk to you next time

1004.33

[Music]