Nix 的另一个成功故事

2021-08-06 07:41:01

昨天我发现自己处于需要知道 Postgres 数据库中表的依赖关系图的位置。我想别人已经写了一个程序来解决这个问题,一些快速的谷歌显示我是正确的。我偶然发现了这篇文章,其中包含一个 Python 脚本,该脚本生成了我正在寻找的依赖图并将其转储到 Graphviz DOT。美丽的! from optparse import OptionParser , OptionGroup import psycopg2 import sys def writedeps ( cursor , tbl ): sql = """ SELECT tc.constraint_name, tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_schema_name FROM information table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name = tc.constraint_name WHEREconstraint_name = tc.constraint_name WHEREconstraint_name = 'KEY ' '和'KEY 'constraint_name'光标。对游标中的行执行 (sql%tbl)。 fetchall(): 约束、表、列、foreign_table、foreign_column = 行打印 '" %s " -> " %s " [label=" %s "]; '%(tbl,foreign_table,constraint)def get_tables(游标):游标。为游标中的行执行(“SELECT tablename FROM pg_tables WHERE schemaname ='public'”)。 fetchall():yield row[0] def main():parser=OptionParser()group=OptionGroup(parser,“数据库选项”)组。 add_option (" --dbname ", action =" store ", dest =" dbname ", help ="数据库名称。") group . add_option (" --dbhost ", action =" store ", dest =" dbhost ", default =" localhost ", help =" The database host.") group 。 add_option (" --dbuser ", action =" store ", dest =" dbuser ", help ="数据库用户名。") 组。 add_option (" --dbpass ", action =" store ", dest =" dbpass ", help ="数据库密码。") 解析器。 add_option_group(group)(options,args)=解析器。 parse_args() 如果不是 options 。 dbname : 打印“请提供数据库名称,有关详细信息,请参阅 --help。” sys 。退出 (1) 尝试: conn = psycopg2 。 connect (" dbname=' %s ' user=' %s ' host=' %s ' password=' %s ' " % ( options . dbname , options . dbuser , options . dbhost , options . dbpass )) 除了 psycopg2。 OperationalError , e : 打印“无法连接到数据库”,打印“也许您需要提供身份验证详细信息:\n %s” % str (e) 打印“使用 --help 获取更多信息。” sys .退出(1)游标= conn。 cursor() print " Digraph F { \n" print 'ranksep=1.0;大小="18.5, 15.5";等级目录=LR; ' for i in get_tables ( cursor ): writedeps ( cursor , i ) print "}" sys . exit ( 0 ) if __name__ == " __main__ ": main () 该脚本依赖于 psycopg2,这意味着我需要处理 Python 依赖管理我可以从打印语句中得知该脚本是用 Python 2 编写的,而我的工作 Macbook 有 Python 3 我的直接想法是使用 Nix 来解决这个问题。我从 NixOS wiki 的 Packaging/Python 部分获取了一个 shell.nix 模板,并添加了 psycopg2 依赖项和 graphviz:

with import <nixpkgs> {}; stdenv.mkDerivation { name = "pip-env"; buildInputs = [ + graphviz + # 系统要求。 readline # Python 要求(足以让 virtualenv 运行)。 python27Full python27Packages.virtualenv python27Packages.pip + python27Packages.psycopg2 ];源代码 = 空; shellHook = '' # 允许使用轮子。 SOURCE_DATE_EPOCH=$(date +%s) # 增加动态链接器路径 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${R}/lib/R/lib:$ {readline}/lib ''; } python database_dependency_order.py -- dbname < NAME > - -dbhost < HOST > - -dbuser < USER > - -dbpass < PASSWORD > |点 - Tpng > deps.png