sqleton
sqleton copied to clipboard
Add PlantUML support
Thanks for the fantastic tool. I would appreciate something more human readable like PlantUML.
I wrote this little script that might help with the idea. It's a hacky script and not in JS so yeah... IDK if it is any good or useful for the dev team (in case considering the idea), but I leave it here just in case somebody wants to use it.
#!/bin/sh
# Convert a SQL database to Plantuml
# $1: Database file
# $2: (Optional) Output name (exluding the extension)
# TODO convert sql to plantuml
out="${2:-$1}.plantuml"
sqleton "$1" -o "$1.plain" || exit 1
[ -f "$out" ] && echo "File '$out' already exists" && exit 1
head "$1.plain" -n-1 | tail -n+2 | awk '
BEGIN {
INDENT = " ";
print "@startuml ERD\n";
}
{
if ($1 == "node") {
print "entity " $2 " {";
split($0, row, "|");
rows = split(row[2], data, ">");
# data[1] => table tag
# loop:
# data[2..3] => tr and td tags
# data[4] => field name + font tag
# data[5] => bold tag
# data[6] => type + bold closing
# data[7] => font closing
# data[8..9] => tr and td tags closing
if (rows >= 4 + 7) process(data[4], data[6]);
for (i=12; i <= rows - 7; i = i + 8) process(data[i], data[i + 2]);
print "}\n";
} else if ($1 == "edge") {
print $2 " --> " $3;
}
}
END {
print "\n@enduml";
}
function remove_tags(s){
sub(/ ?<.*/, "", s);
sub(/^ ?/, "", s);
return s;
}
function process(field, type) {
field = remove_tags(field);
type = remove_tags(type);
printf INDENT;
# Move the star of pks to the back
match(field, "*");
if (RLENGTH != -1) field = "* " substr(field, 0, length(field) - RLENGTH);
printf field " : " type;
if (RLENGTH != -1) printf "\n" INDENT "--";
print "";
}
' >"$out"
rm "$1.plain"
This does the conversion below which can be rendered to something like that picture:
graph 1 10.972 11.694
node django_migrations 6.8228 7.9533 2.0833 1.4583 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>django_migrations</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">app <font ><b>varchar(255)</b></font></td></tr><tr><td align="left">name <font ><b>varchar(255)</b></font></td></tr><tr><td align="left">applied <font ><b>datetime</b></font></td></tr></table>> solid Mrecord black lightgrey
node auth_group_permissions 1.3378 3.3616 2.6667 1.2222 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>auth_group_permissions</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">group_id <font ><b>integer</b></font></td></tr><tr><td align="left">permission_id <font ><b>integer</b></font></td></tr></table>> solid Mrecord black lightgrey
node auth_user_groups 8.49 0.86986 2 1.2222 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>auth_user_groups</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">user_id <font ><b>integer</b></font></td></tr><tr><td align="left">group_id <font ><b>integer</b></font></td></tr></table>> solid Mrecord black lightgrey
node auth_user_user_permissions 5.4561 5.548 3.0556 1.2222 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>auth_user_user_permissions</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">user_id <font ><b>integer</b></font></td></tr><tr><td align="left">permission_id <font ><b>integer</b></font></td></tr></table>> solid Mrecord black lightgrey
node django_admin_log 9.5613 9.7449 2.8333 2.4028 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>django_admin_log</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">action_time <font ><b>datetime</b></font></td></tr><tr><td align="left">object_id <font ><b>text</b></font></td></tr><tr><td align="left">object_repr <font ><b>varchar(200)</b></font></td></tr><tr><td align="left">change_message <font ><b>text</b></font></td></tr><tr><td align="left">content_type_id <font ><b>integer</b></font></td></tr><tr><td align="left">user_id <font ><b>integer</b></font></td></tr><tr><td align="left">action_flag <font ><b>smallint unsigned</b></font></td></tr></table>> solid Mrecord black lightgrey
node django_content_type 5.024 11.086 2.2917 1.2222 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>django_content_type</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">app_label <font ><b>varchar(100)</b></font></td></tr><tr><td align="left">model <font ><b>varchar(100)</b></font></td></tr></table>> solid Mrecord black lightgrey
node auth_permission 2.31 7.1659 2.3472 1.4583 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>auth_permission</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">content_type_id <font ><b>integer</b></font></td></tr><tr><td align="left">codename <font ><b>varchar(100)</b></font></td></tr><tr><td align="left">name <font ><b>varchar(255)</b></font></td></tr></table>> solid Mrecord black lightgrey
node auth_group 4.6199 0.49404 2 0.98611 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>auth_group</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">name <font ><b>varchar(150)</b></font></td></tr></table>> solid Mrecord black lightgrey
node auth_user 9.7531 5.6411 2.3472 3.1111 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>auth_user</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">id* <font ><b>integer</b></font></td></tr><tr><td align="left">password <font ><b>varchar(128)</b></font></td></tr><tr><td align="left">last_login <font ><b>datetime</b></font></td></tr><tr><td align="left">is_superuser <font ><b>bool</b></font></td></tr><tr><td align="left">username <font ><b>varchar(150)</b></font></td></tr><tr><td align="left">last_name <font ><b>varchar(150)</b></font></td></tr><tr><td align="left">email <font ><b>varchar(254)</b></font></td></tr><tr><td align="left">is_staff <font ><b>bool</b></font></td></tr><tr><td align="left">is_active <font ><b>bool</b></font></td></tr><tr><td align="left">date_joined <font ><b>datetime</b></font></td></tr><tr><td align="left">first_name <font ><b>varchar(150)</b></font></td></tr></table>> solid Mrecord black lightgrey
node django_session 4.8228 3.495 2.4167 1.2222 <<table border="0" cellspacing="0.5"><tr><td align="left" height="24" valign="bottom"><font point-size="13"><b>django_session</b></font></td></tr></table>|<table border="0" cellspacing="0.5" width="134"><tr><td align="left">session_key* <font ><b>varchar(40)</b></font></td></tr><tr><td align="left">session_data <font ><b>text</b></font></td></tr><tr><td align="left">expire_date <font ><b>datetime</b></font></td></tr></table>> solid Mrecord black lightgrey
edge auth_group_permissions auth_permission 4 1.4929 3.9686 1.6558 4.6058 1.913 5.6123 2.0953 6.3256 solid black
edge auth_group_permissions auth_group 4 2.0299 2.7569 2.6029 2.2563 3.4112 1.5501 3.9717 1.0603 solid black
edge auth_user_groups auth_group 4 7.4883 0.77259 6.953 0.72061 6.2925 0.65646 5.7402 0.60283 solid black
edge auth_user_groups auth_user 4 8.65 1.4741 8.8161 2.1018 9.0835 3.1116 9.3133 3.9799 solid black
edge auth_user_user_permissions auth_permission 4 4.2801 6.1527 4.0546 6.2687 3.8175 6.3907 3.5889 6.5082 solid black
edge auth_user_user_permissions auth_user 4 6.9892 5.5812 7.4714 5.5916 7.9987 5.6031 8.4623 5.6131 solid black
edge django_admin_log django_content_type 4 8.1443 10.164 7.547 10.34 6.8576 10.544 6.279 10.715 solid black
edge django_admin_log auth_user 4 9.6173 8.5469 9.6354 8.1581 9.6559 7.7196 9.6754 7.3033 solid black
edge auth_permission django_content_type 4 2.8109 7.8895 3.3035 8.6009 4.0503 9.6796 4.5377 10.384 solid black
stop
@startuml ERD
entity django_migrations {
* id : integer
--
app : varchar(255)
name : varchar(255)
applied : datetime
}
entity auth_group_permissions {
* id : integer
--
group_id : integer
permission_id : integer
}
entity auth_user_groups {
* id : integer
--
user_id : integer
group_id : integer
}
entity auth_user_user_permissions {
* id : integer
--
user_id : integer
permission_id : integer
}
entity django_admin_log {
* id : integer
--
action_time : datetime
object_id : text
object_repr : varchar(200)
change_message : text
content_type_id : integer
user_id : integer
action_flag : smallint unsigned
}
entity django_content_type {
* id : integer
--
app_label : varchar(100)
model : varchar(100)
}
entity auth_permission {
* id : integer
--
content_type_id : integer
codename : varchar(100)
name : varchar(255)
}
entity auth_group {
* id : integer
--
name : varchar(150)
}
entity auth_user {
* id : integer
--
password : varchar(128)
last_login : datetime
is_superuser : bool
username : varchar(150)
last_name : varchar(150)
email : varchar(254)
is_staff : bool
is_active : bool
date_joined : datetime
first_name : varchar(150)
}
entity django_session {
* session_key : varchar(40)
--
session_data : text
expire_date : datetime
}
auth_group_permissions --> auth_permission
auth_group_permissions --> auth_group
auth_user_groups --> auth_group
auth_user_groups --> auth_user
auth_user_user_permissions --> auth_permission
auth_user_user_permissions --> auth_user
django_admin_log --> django_content_type
django_admin_log --> auth_user
auth_permission --> django_content_type
@enduml

Cool, thanks for sharing!
That's great for all. It's high-effort, powerful and simple for user and even developer! Thanks for sharing.