Fork me on GitHub
#sql
<
2019-05-18
>
emccue09:05:22

possibly a simple question and possibly a rabbit hole:

emccue09:05:54

in something like django you write model classes and and automated tool comes up with all the sql needed to create the tables for your app

emccue09:05:11

and later on if you change those classes that same automated tool will write the "migrations" to upgrade an old instance of the database (like a previous deploy) to the new schema that your model classes imply without dropping all your data

bja09:05:56

Eh, it does that to varying levels of success

emccue09:05:58

if we create those tables manually how exactly does one go about writing migrations by hand

bja09:05:39

I think most people use a migrations framework to run either .clj files representing migrations or .SQL files

bja09:05:15

You can find some that are language-agnostic and clojure-spe ific ones like migratus

emccue09:05:15

from the luminus docs

emccue09:05:45

but that is all about organizing "migrations" and making sure they are ordered and whatnot

emccue09:05:55

I still dont understand how to write migrations

bja09:05:18

For example, at my last gig, we had a directory of migrations that were timestamped, named, and given a direction, but were just SQL files

emccue09:05:29

CREATE TABLE IF NOT EXISTS, SELECT, and INSERT is about the limit of my sql knowledge

bja09:05:41

We had a simple runner to apply them and track which ones were applied

bja09:05:14

When we did that, schema and data migrations often lived side by side (albeit in different individual files)

bja09:05:53

For that, you should read up on your SQL dialects ddl syntax

emccue09:05:57

like say i had this file

bja09:05:14

Postgres and mysql both have good sections on it in their docs

emccue09:05:31

CREATE TABLE IF NOT EXISTS MYTABLE (
    id INTEGER PRIMARY KEY,
    a TEXT NOT NULL
);

bja09:05:33

DDL is the magic keyword you're looking for

emccue09:05:40

how would i write a migration to add a b?

emccue09:05:45

okay thats a start

bja09:05:36

Alter table

emccue09:05:24

how would your simple runner track which ones were applied?

bja09:05:18

It kept a stateful table which inserted the migration id/filename and a timestamp

bja09:05:26

That's how most of them work

bja09:05:35

I wouldn't recommend rolling your own

bja09:05:07

We did for $reasons

emccue09:05:23

NIH syndrome or are most proprietary?

bja09:05:25

Which weren't very strong

bja09:05:50

A misplaced desire to have proprietary stuff

emccue09:05:10

do you know any good open source ones that match up with what you had?

emccue09:05:14

clojure or not

bja09:05:23

You can use it as a standalone comma d line tool

bja09:05:28

Or as a java library

bja09:05:39

But it can work with a raw directory of .SQL files

bja09:05:55

I prefer that because I never had cookie-cutter schemas

bja09:05:39

Even if I used something like Django migrations, I'd end up writing the migrations as raw SQL anyway

bja09:05:21

Although I hear that Django migrations and their or have come a long way since the 1.5 days I was using the framework

bja09:05:45

I haven't looked back from static queries and honeysql as an ast to build dynamic queries using clojure

bja09:05:44

The power of jdbc tooling and a way to work with SQL as an ast has been a very powerful to utilize

bja09:05:45

To fully utilize my target database's featureset while reducing/factoring out crud.

emccue09:05:01

reading their docs now

emccue09:05:07

always annoying to see "pro" and "enterprise" editions

emccue09:05:27

even if it makes perfect real world sense

kulminaator10:05:54

for a while i thought i knew quite alot about db migration systems ...

kulminaator10:05:22

but then around 2011 in skype our db team built a tool called relman ... and then we understood that a whole lot of things we had done before were just awful πŸ˜„

kulminaator10:05:21

the essence of the tool was that your repo described the desired state, not the series of mutations ... and the tool figured out that ok, right the tables and schemas are in state A and you want to get into state B , so it has to do the following mutations to it ...

kulminaator10:05:55

the nice part was that you could always open the repo and understand what is actually there in production, how does it look, what tables are there, what indexes etc.

kulminaator10:05:35

if you have a repo that has 200 migrations on it (and obviously missing 5 manual ones that dba's applied to put out fires) ... you can see 200 migrations but rarely what the actual state of the production databases is

kulminaator10:05:18

this gets especially wild if you have similar databases in clusters and you need to understand that a logical replica is skipping a few columns when talking to a specific reporting replica and it's by design, not by accident.

kulminaator10:05:32

but sadly i haven't seen such a tool in the open source world 😞

kulminaator10:05:01

another useful feature was that you could just diff repository revisions to understand what has happened to the database , instead of looking at 5-6 migrations and calculating on your fingers what the state could/should have been ... (or instead of manually setting up databases and playing 195 and 200 migrations on them accordingly)

kulminaator10:05:27

the tool that has awareness of the changes that you want to perform can also be a bit smarter on avoiding/pointing out possible deadlocks on applying. if you just write manual sql that all relies on you πŸ˜‰

emccue10:05:33

out of curiosity, how long did that internal tool take to develop?

emccue10:05:19

I am guessing there is some sizable set of issues that makes "oh just do a diff" more complicated than it sounds on the surface level

kulminaator11:05:19

it took a few developer months πŸ™‚

kulminaator11:05:09

but considering how many devs we had who had to do db stuff without breaking things - it was a good investment

gklijs12:05:28

Seems not that hard, although handling possible type changes, differences in indexes, and possible stores procedures and stuff might make things difficult.

kulminaator12:05:23

yep. but for some reason majority of the tools are stuck in the opposing "track your changes instead" ideology ...

kulminaator12:05:10

when we write code we change the code ... but for some reason on the databases we tend to write the initial code and then we try to follow up with the patches to the original design πŸ™‚

kulminaator12:05:40

would feel pretty weird to manage code this way , wouldn't it ?

emccue16:05:09

how involved with the project were you?

emccue16:05:08

...with the implicit "were you involved enough that you would know enough to facilitate making an open source version"

emccue16:05:55

maybe a partial solution would be a tool that runs all the migrations and flattens out what the db is now

dominicm17:05:30

Django has a tool exactly like this

emccue17:05:17

yeah but thats attached to the whole django ORM thing right?

emccue17:05:31

not that i don't like the ORM

emccue17:05:48

but part of me is just hunting for a solution to this stuff for clojure

kulminaator19:05:09

that was totally not-orm πŸ™‚ ...

kulminaator19:05:33

i was very well aware of the internal workings of the tooling but i have no time on my hands to invest anywhere, family just eats it all away for now

kulminaator19:05:47

the django tool that @dominicm mentioned , it actually handles transformations from one table state to another ? (meaning when you declare in a newer version that your table has a new column with an index but doesn't have a column that was previously mentioned -> it adds the new column, drops the old one and adds the index concurrently on the side ?)

kulminaator19:05:02

i don't use django so i wouldn't know πŸ™‚

kulminaator19:05:21

i must be looking at the wrong django manual ... dominic when you can - point a link to me of what you had in your vision there πŸ™‚

emccue19:05:50

A clip from Nathan for you

seancorfield19:05:01

What has it to do with SQL?

emccue19:05:27

response to kulminaator's time commitments

seancorfield19:05:27

It's why startups are full of single guys πŸ™‚

dominicm21:05:35

https://docs.djangoproject.com/en/2.1/topics/migrations/ > Your models will be scanned and compared to the versions currently contained in your migration files, and then a new set of migrations will be written out. Make sure to read the output to see what makemigrations thinks you have changed - it’s not perfect, and for complex changes it might not be detecting what you expect. Model examples: https://docs.djangoproject.com/en/2.1/topics/db/models/ (probably links to documentation about generating migrations too)

kulminaator09:05:18

ah ok, got it.