Esempio n. 1
0
def test_single_table():

    objects, relations, inherits = sadisplay.describe([model.notes])
    assert len(objects) == 1
    assert relations == []
    assert inherits == []

    assert objects[0] == {
        'name':
        model.notes.name,
        'cols': [
            ('INTEGER', 'id', 'pk'),
            ('INTEGER', 'user_id', 'fk'),
            ('VARCHAR(150)', 'body', None),
            ('VARCHAR(50)', 'name', None),
        ],
        'indexes': [{
            'cols': ['body'],
            'name': 'ix_notes_body'
        }, {
            'cols': ['name'],
            'name': 'ix_notes_name'
        }],
        'props': [],
        'methods': [],
    }
Esempio n. 2
0
def test_single_mapper():

    objects, relations, inherits = sadisplay.describe([model.User])

    assert len(objects) == 1
    assert relations == []
    assert inherits == []
    assert objects[0] == {
        'name':
        model.User.__name__,
        'cols': [
            ('INTEGER', 'id', 'pk'),
            ('VARCHAR(50)', 'name', None),
        ],
        'indexes': [{
            'cols': ['name', 'department'],
            'name': 'ix_username_department',
        }],
        'props': [
            'address',
            'books',
        ],
        'methods': [
            'login',
        ],
    }
Esempio n. 3
0
def get_dot_schema(db):
    # Identify the parameters for the database
    engine = create_engine('sqlite:///databases.db')
    Base.metadata.bind = engine  
    DBSession = sessionmaker(bind=engine)
    session = DBSession()
    db = session.query(Database).filter(Database.id == db).first()
    
    if db is None:
        raise Exception("There are no databases identified by " + db)
    
    # Get the dot file
    url = str(URL(db.engine, database = db.name))
    engine = create_engine(url)
    meta = MetaData()

    meta.reflect(bind=engine)
    
    tables = set(meta.tables.keys())

    desc = describe(map(lambda x: operator.getitem(meta.tables, x), tables))
    graph_file = to_dot(desc)
    with open('new.dot', 'w') as file:
        file.write(graph_file)
    return graph_file
 def render_vars(self, request):
     tables = self.Base.metadata.tables.values()
     desc = sadisplay.describe(tables)
     dot_data = sadisplay.dot(desc)
     graph = pydot.graph_from_dot_data(str(dot_data))
     svg_img = graph.create_svg()
     return {'svg_img': svg_img}
Esempio n. 5
0
def generate(extent="all",
             save_dotfile="",
             save_plot="",
             label="",
             linker_tables=False):
    """Retreive the LabbookDB schema and save either a DOT file, or a PNG or PDF plot.
	"""

    if extent == "all":
        nodes = ALLOWED_CLASSES.values()
    elif type(extent) is list:
        nodes = [ALLOWED_CLASSES[key] for key in extent]

    if linker_tables:
        nodes.extend(linker_tables)

    desc = sadisplay.describe(nodes)

    if save_dotfile:
        save_dotfile = path.abspath(path.expanduser(save_dotfile))
        with codecs.open(save_dotfile, 'w', encoding='utf-8') as f:
            f.write(sadisplay.dot(desc))

    if save_plot:
        save_plot = path.abspath(path.expanduser(save_plot))
        dot = sadisplay.dot(desc)
        dot = dot.replace('label = "generated by sadisplay v0.4.8"',
                          'label = "{}"'.format(label))
        graph = pydotplus.graph_from_dot_data(dot)
        filename, extension = path.splitext(save_plot)
        if extension in [".png", ".PNG"]:
            graph.write_png(save_plot)
        elif extension in [".pdf", ".PDF"]:
            graph.write_pdf(save_plot)
def _build_desc():
    return sadisplay.describe(
        [getattr(models, attr) for attr in dir(models)],
        show_methods=True,
        show_properties=True,
        show_indexes=True,
    )
Esempio n. 7
0
def create_uml_files(list_of_models, file_prefix):
    desc = sadisplay.describe(list_of_models)
    path_prefix = os.path.join(base_folder, file_prefix)
    with codecs.open(path_prefix + '.dot', 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc))
    os.system(''.join(
        ['dot -Tpng ', path_prefix, '.dot > ', path_prefix, '.png']))
def _build_desc():
    return sadisplay.describe(
        [getattr(models, attr) for attr in dir(models)],
        show_methods=True,
        show_properties=True,
        show_indexes=True,
    )
Esempio n. 9
0
def generate_schema():
    p_dot = Path(BASE_DIR, 'utils', 'schema.dot')
    p_png = Path(BASE_DIR, 'utils', 'schema.png')

    desc = sadisplay.describe(
        [getattr(models, attr) for attr in dir(models)],
        show_methods=True,
        show_properties=True,
        show_indexes=True,
    )

    with codecs.open(p_dot, 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc))

    with open(p_dot, 'r', encoding='utf-8') as f:
        s = f.read()
    with open(p_dot, 'w', encoding='cp1251') as f:
        f.write(s.encode('cp1251', errors='ignore').decode('cp1251'))

    if os.name == 'nt':
        try:
            from .config_dot_win import DOT_PATH
        except ModuleNotFoundError:
            pass
        else:
            os.environ["PATH"] += os.pathsep + DOT_PATH

    try:
        (graph, ) = pydot.graph_from_dot_file(p_dot, encoding='utf-8')
        graph.write_png(p_png)
    except FileNotFoundError as e:
        print(e.args[1])
        if e.args[1] == '"dot" not found in path.':
            print('Probably "dot" not installed')
 def render_vars(self, request):
     tables = self.Base.metadata.tables.values()
     desc = sadisplay.describe(tables)
     dot_data = sadisplay.dot(desc)
     graph = pydot.graph_from_dot_data(str(dot_data))
     svg_img = graph.create_svg()
     return {'svg_img': svg_img}
Esempio n. 11
0
def cmd_describe(g, opts):
    """
        Describe DB by printing SQL schema, or diagram.
    """
    if g.database_tables:
        reload_metadata(g)
    if hasattr(schema, 'models'):
        models = schema.models
    #[getattr(model, attr) for attr in dir(model)],
    models = [
            getattr(schema, x) for x in dir(schema)
            if inspect.isclass(getattr(schema, x))
                and issubclass( getattr(schema, x), schema.SqlBase ) ]
    #metadata.reflect(engine)
    if g.diagram:
        dia = g.diagram
        name = opts.args.schema
        desc = sadisplay.describe(
            models,
            show_methods=True,
            show_properties=True,
            show_indexes=True,
        )
        with codecs.open(name+'.'+dia, 'w', encoding='utf-8') as f:
            f.write(getattr(sadisplay, dia)(desc))

    elif not g.quiet or g.output:
        # Print
        out = reporter.Reporter(out=opts.output)
        for table in metadata.tables.values():
            reporter.stdout.Table(table)

    else:
        return 1
Esempio n. 12
0
def Creatediagram():
    desc = sadisplay.describe(globals().values())

    with codecs.open('schema.plantuml', 'w', encoding='utf-8') as f:
        f.write(sadisplay.plantuml(desc))

    with codecs.open('schema.dot', 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc))
def show_database_schema(
    schemastem: str,
    make_image: bool = False,
    java: str = None,
    plantuml: str = None,
    height_width_limit: int = 20000,
    java_memory_limit_mb: int = 2048,
) -> None:
    """
    Prints the database schema to a PNG picture.

    Args:
        schemastem:
            filename stem
        make_image:
            Make a PNG image? (May be impractically large!)
        java:
            (for ``make_image``) Java executable
        plantuml:
            (for ``make_image``) PlantUML Java ``.jar`` file
        height_width_limit:
            (for ``make_image``) maximum height and width for PNG; see
            https://plantuml.com/faq
        java_memory_limit_mb:
            (for ``make_image``) Java virtual machine memory limit, in Mb
    """
    # noinspection PyUnresolvedReferences
    import camcops_server.camcops_server_core as core  # delayed import; import side effects  # noqa
    import sadisplay  # delayed import
    import camcops_server.cc_modules.cc_all_models as models  # delayed import

    # ... a re-import to give it a name
    uml_filename = f"{schemastem}.plantuml"
    png_filename = f"{schemastem}.png"
    log.info(f"Making schema PlantUML: {uml_filename}")
    desc = sadisplay.describe([getattr(models, attr) for attr in dir(models)])
    # log.debug(desc)
    with open(uml_filename, "w") as f:
        f.write(sadisplay.plantuml(desc))
    if make_image:
        import shutil  # delayed import

        assert shutil.which(java), f"Can't find Java executable: {java}"
        assert os.path.isfile(
            plantuml
        ), f"Can't find PlantUML JAR file: {plantuml}"  # noqa
        log.info(f"Making schema PNG: {png_filename}")
        cmd = [
            java,
            f"-Xmx{java_memory_limit_mb}m",
            f"-DPLANTUML_LIMIT_SIZE={height_width_limit}",
            "-jar",
            plantuml,
            uml_filename,
        ]
        log.info("Arguments: {}", cmd)
        subprocess.check_call(cmd)
Esempio n. 14
0
def main():
    classes = [c for c in
            list(chain.from_iterable([[getattr(m, a) for a in dir(m)]
                for m in (terms, factset, network)]))
            if type(c) is DeclarativeMeta and issubclass(c, Base)]
    print(classes)

    desc = sadisplay.describe(classes, show_methods=False)
    open('schema.plantuml', 'w').write(sadisplay.plantuml(desc))
    open('schema.dot', 'w').write(sadisplay.dot(desc))
Esempio n. 15
0
def render(self, node):

    all_names = []

    for module_name in node['module']:
        __import__(module_name, globals(), locals())
        module = sys.modules[module_name]

        for attr in dir(module):
            try:
                m = getattr(module, attr)

                # !!!
                # Ugly hack
                repr(m)  # without this statement - exception raises
                # any ideas?

                all_names.append(m)
            except:
                pass

    names = []

    if node['exclude']:
        for i in all_names:
            try:
                if i.__name__ not in node['exclude']:
                    names.append(i)
            except AttributeError:
                pass

    elif node['include']:
        for i in all_names:
            try:
                if i.__name__ in node['include']:
                    names.append(i)
            except AttributeError:
                pass

    else:
        names = all_names

    desc = sadisplay.describe(names)

    render = node['render'] or self.builder.config.sadisplay_default_render

    if render == 'plantuml':
        content = sadisplay.plantuml(desc)
        command = generate_plantuml_args(self)
    elif render == 'graphviz':
        content = sadisplay.dot(desc)
        command = generate_graphviz_args(self)

    return render_image(self, content, command)
Esempio n. 16
0
def render(self, node):

    all_names = []

    for module_name in node['module']:
        __import__(module_name, globals(), locals(), [], -1)
        module = sys.modules[module_name]

        for attr in dir(module):
            try:
                m = getattr(module, attr)

                # !!!
                # Ugly hack
                repr(m) # without this statement - exception raises
                # any ideas?

                all_names.append(m)
            except:
                pass

    names = []

    if node['exclude']:
        for i in all_names:
            try:
                if i.__name__ not in node['exclude']:
                    names.append(i)
            except AttributeError:
                pass

    elif node['include']:
        for i in all_names:
            try:
                if i.__name__ in node['include']:
                    names.append(i)
            except AttributeError:
                pass

    else:
        names = all_names

    desc = sadisplay.describe(names)

    render = node['render'] or self.builder.config.sadisplay_default_render

    if render == 'plantuml':
        content = sadisplay.plantuml(desc)
        command = generate_plantuml_args(self)
    elif render == 'graphviz':
        content = sadisplay.dot(desc)
        command = generate_graphviz_args(self)

    return render_image(self, content, command)
Esempio n. 17
0
def get_ulm():
    desc = sadisplay.describe(
        [getattr(models, attr) for attr in dir(models)],
        show_methods=True,
        show_properties=True,
        show_indexes=True,
    )
    with codecs.open('doc/database/schema.plantuml', 'w',
                     encoding='utf-8') as f:
        f.write(sadisplay.plantuml(desc))
    with codecs.open('doc/database/schema.dot', 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc))
Esempio n. 18
0
def models_diagram():
    default_models = db.load_default_models()
    models = [
        m for m in util.collect_subclasses(db.Model)
        if sys.modules[m.__module__] != default_models
    ]

    desc = sadisplay.describe(models,
                              show_methods=True,
                              show_properties=True,
                              show_indexes=True)

    return sadisplay.dot(desc)
Esempio n. 19
0
def generate_schema_dot():
    """
    Generate a .dot file for the current database schema.
    Render the graphviz directed graphs with:
        $ dot -Tpng schema.dot > schema.png
    """
    import sys
    import sadisplay
    reload(sys)
    sys.setdefaultencoding('utf8')
    desc = sadisplay.describe(globals().values())

    with open('schema.dot', 'w') as f:
        f.write(sadisplay.dot(desc))
Esempio n. 20
0
def make_dependencies():
    model = sadisplay.describe([getattr(models, attr) for attr in dir(models)])
    tables = model[0]
    relations = model[1]

    names = [table['name'] for table in tables]
    dep_tree = {}

    for name in names:
        dep_tree[name] = set()
        for rel in relations:
            if name == rel['from']:
                dep_tree[name] ^= {rel['to']}

    return dep_tree
Esempio n. 21
0
def main():
    with tempfile.NamedTemporaryFile() as fp:
        sqlite_db_name = fp.name
        SqliteAccountInfo(sqlite_db_name)
        engine = create_engine('sqlite:///' + sqlite_db_name)

        meta = MetaData()

        meta.reflect(bind=engine)

        tables = set(meta.tables.keys())

        desc = describe(
            map(lambda x: operator.getitem(meta.tables, x), sorted(tables)))
        print(getattr(render, 'dot')(desc).encode('utf-8'))
Esempio n. 22
0
def generate_erd():
    """
    Generate UML that represents an ERD

    Command wrapper for sadisplay. Must have graphviz installed.
    See https://bitbucket.org/estin/sadisplay/wiki/Home
    """
    import sadisplay
    from ton import models

    desc = sadisplay.describe([getattr(models, attr) for attr in dir(models)])
    with open('schema.dot', 'w') as f:
        f.write(sadisplay.dot(desc))
    ret = call("dot -Tpng schema.dot > schema.png", shell=True)
    if ret == 0:
        os.remove("schema.dot")
Esempio n. 23
0
def render(self, node):

    all_names = []

    for module_name in node['module']:
        __import__(module_name, globals(), locals(), [], -1)
        module = sys.modules[module_name]

        all_names += [getattr(module, attr) for attr in dir(module)]

    names = []

    if node['exclude']:
        for i in all_names:
            try:
                if i.__name__ not in node['exclude']:
                    names.append(i)
            except AttributeError:
                pass

    elif node['include']:
        for i in all_names:
            try:
                if i.__name__ in node['include']:
                    names.append(i)
            except AttributeError:
                pass

    else:
        names = all_names

    desc = sadisplay.describe(names)

    render = node['render'] or self.builder.config.sadisplay_default_render

    if render == 'plantuml':
        content = sadisplay.plantuml(desc)
        command = generate_plantuml_args(self)
    elif render == 'graphviz':
        content = sadisplay.dot(desc)
        command = generate_graphviz_args(self)

    return render_image(self, content, command)
Esempio n. 24
0
    def test_single_mapper(self):

        objects, relations, inherits = sadisplay.describe([model.User])

        assert len(objects) == 1
        assert relations == []
        assert inherits == []
        assert_equal(
            objects[0],
            {
                'name': model.User.__name__,
                'cols': [
                    ('INTEGER', 'id', 'pk'),
                    ('VARCHAR(50)', 'name', None),
                ],
                'props': ['address', 'books', ],
                'methods': ['login', ],
            }
        )
Esempio n. 25
0
def render(self, node):

    all_names = []

    for module_name in node["module"]:
        __import__(module_name, globals(), locals(), [], -1)
        module = sys.modules[module_name]

        all_names += [getattr(module, attr) for attr in dir(module)]

    names = []

    if node["exclude"]:
        for i in all_names:
            try:
                if i.__name__ not in node["exclude"]:
                    names.append(i)
            except AttributeError:
                pass

    elif node["include"]:
        for i in all_names:
            try:
                if i.__name__ in node["include"]:
                    names.append(i)
            except AttributeError:
                pass

    else:
        names = all_names

    desc = sadisplay.describe(names)

    render = node["render"] or self.builder.config.sadisplay_default_render

    if render == "plantuml":
        content = sadisplay.plantuml(desc)
        command = generate_plantuml_args(self)
    elif render == "graphviz":
        content = sadisplay.dot(desc)
        command = generate_graphviz_args(self)

    return render_image(self, content, command)
Esempio n. 26
0
def models_diagram(fmt="dot"):
    parsers = {
        "dot": sadisplay.dot,
        "plantuml": sadisplay.plantuml,
    }
    parser = parsers[fmt]

    default_models = db.load_default_models()
    models = [
        m for m in util.collect_subclasses(db.Model)
        if sys.modules[m.__module__] != default_models]

    desc = sadisplay.describe(
        models,
        show_methods=True,
        show_properties=True,
        show_indexes=True)

    return parser(desc)
Esempio n. 27
0
def generate_schema(schema_file: str,
                    include=None,
                    include_performance_models=True):
    """Generate an image out of the current schema."""
    try:
        import sadisplay
        import pydot
    except ImportError:
        _LOGGER.error(
            "Failed to import required libraries to perform schema generation")
        raise

    import thoth.storages.graph.models_performance as performance_models

    from thoth.storages.graph.models import ALL_MAIN_MODELS
    from thoth.storages.graph.models import ALL_RELATION_MODELS

    all_models = list(ALL_MAIN_MODELS.union(ALL_RELATION_MODELS))

    if include:
        desc_models = [
            m for m in all_models if any(
                re.fullmatch(p, m.__name__) for p in include)
        ]
    else:
        desc_models = all_models

    if include_performance_models:
        desc_models += list(vars(performance_models).values())

    desc = sadisplay.describe(
        desc_models,
        show_methods=True,
        show_properties=True,
        show_indexes=False,
        show_simple_indexes=False,
        show_columns_of_indexes=False,
    )
    dot_data = sadisplay.dot(desc)
    graph, = pydot.graph_from_dot_data(dot_data)
    _LOGGER.info("Writing schema to %r...", schema_file)
    graph.write_png(schema_file)
Esempio n. 28
0
    def test_single_table(self):

        objects, relations, inherits = sadisplay.describe([model.notes])
        assert len(objects) == 1
        assert relations == []
        assert inherits == []

        assert_equal(
            objects[0],
            {
                'name': model.notes.name,
                'cols': [
                    ('INTEGER', 'id', 'pk'),
                    ('INTEGER', 'user_id', 'fk'),
                    ('VARCHAR(50)', 'name', None),
                ],
                'props': [],
                'methods': [],
            }
        )
Esempio n. 29
0
def rel(file_format):
    ''' outputs relational diagram into rel.png '''
    try:
        from sh import dot, cp
        desc = sadisplay.describe([
            User,
            Role,
            Reservation,
            Room,
            Timeslot,
            Weekday,
            reservations_users,
            reservations_timeslots
        ])
        with open('schema.dot', 'w', encoding='utf-8') as f:
            f.write(sadisplay.dot(desc))
            
        
        dot("-T"+file_format, "schema.dot", "-o", "app/static/rel."+file_format)
        
        
    except ImportError as e:
        print(str(e))
Esempio n. 30
0
import sadisplay
from happypanda.core import db

def exclude(attr):
	""
	if attr.endswith('_profiles'):
		return True

	if 'life' == attr.lower():
		return True

	if 'event' == attr.lower():
		return True

	if 'user' == attr.lower():
		return True

attrs = [getattr(db, attr) for attr in dir(db) if not exclude(attr)]

desc = sadisplay.describe(
    attrs,
    show_methods=False,
    show_properties=True,
    show_indexes=False,
 	show_simple_indexes=False,
 	show_columns_of_indexes=False
)

with open('schema.dot', 'w', encoding='utf-8') as f:
    f.write(sadisplay.dot(desc))
Esempio n. 31
0
import octavia.db.models as models

sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.abspath('.'))

from tools import create_flow_docs

# Generate our flow diagrams
create_flow_docs.generate('tools/flow-list.txt',
                          'doc/source/contributor/devref/flow_diagrams')

# Generate entity relationship diagram
desc = sadisplay.describe(
    [getattr(models, attr) for attr in dir(models)],
    show_methods=True,
    show_properties=True,
    show_indexes=True,
)
graph = graphviz.graph_from_dot_data(sadisplay.dot(desc).encode('utf-8'))
graph.write('contributor/devref/erd.svg', format='svg')

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))

# -- General configuration ----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
Esempio n. 32
0
def run():
    """Command for reflection database objects"""
    parser = OptionParser(
        version=__version__,
        description=__doc__, )

    parser.add_option(
        '-u',
        '--url',
        dest='url',
        help='Database URL (connection string)', )

    parser.add_option(
        '-r',
        '--render',
        dest='render',
        default='dot',
        choices=['plantuml', 'dot'],
        help='Output format - plantuml or dot', )

    parser.add_option(
        '-l',
        '--list',
        dest='list',
        action='store_true',
        help='Output database list of tables and exit', )

    parser.add_option(
        '-i',
        '--include',
        dest='include',
        help='List of tables to include through ","', )

    parser.add_option(
        '-e',
        '--exclude',
        dest='exclude',
        help='List of tables to exlude through ","', )

    parser.add_option(
        '-s',
        '--schema',
        dest='schema',
        help='Additional schemas (besides `public`) ","', )

    (options, args) = parser.parse_args()

    if not options.url:
        print('-u/--url option required')
        exit(1)

    engine = create_engine(options.url)
    meta = MetaData()

    # Set schema(s) to reflect
    schema = 'public'
    if options.schema:
        schema = options.schema
    for s in schema.split(','):
        meta.reflect(bind=engine,schema=s)

    if options.list:
        print('Database tables:')
        tables = sorted(meta.tables.keys())

        def _g(l, i):
            try:
                return tables[i]
            except IndexError:
                return ''

        for i in range(0, len(tables), 2):
            print(' {0}{1}{2}'.format(
                _g(tables, i),
                ' ' * (38 - len(_g(tables, i))),
                _g(tables, i + 1), ))

        exit(0)

    tables = set(meta.tables.keys())

    if options.include:
        tables &= set(map(str.strip, options.include.split(',')))

    if options.exclude:
        tables -= set(map(str.strip, options.exclude.split(',')))

    desc = describe(
        map(lambda x: operator.getitem(meta.tables, x), sorted(tables)))
    print(getattr(render, options.render)(desc))
Esempio n. 33
0
import codecs
import sadisplay

import db

if __name__ == '__main__':
    desc = sadisplay.describe([getattr(db, attr) for attr in dir(db)])

    with codecs.open('schema.dot', 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc))
Esempio n. 34
0
def main() -> int:
    """
    Command-line entry point.

    Returns:
        exit code
    """
    # -------------------------------------------------------------------------
    # Arguments
    # -------------------------------------------------------------------------
    parser = argparse.ArgumentParser(
        description="whisker_serial_order v{}. Serial order task for "
        "Whisker.".format(SERIAL_ORDER_VERSION))
    parser.add_argument("--logfile",
                        default=None,
                        help="Filename to append log to")
    parser.add_argument('--verbose',
                        '-v',
                        action='count',
                        default=0,
                        help="Be verbose. (Use twice for extra verbosity.)")
    parser.add_argument('--guilog',
                        action="store_true",
                        help="Show Python log in a GUI window")
    parser.add_argument('--upgrade-database',
                        action="store_true",
                        help="Upgrade database to current version.")
    # parser.add_argument('--debug-qt-signals', action="store_true",
    #                     help="Debug QT signals.")
    parser.add_argument(
        "--dburl",
        default=None,
        help="Database URL (if not specified, task will look in {} "
        "environment variable).".format(DB_URL_ENV_VAR))
    parser.add_argument('--dbecho',
                        action="store_true",
                        help="Echo SQL to log.")
    parser.add_argument(
        "--outdir",
        default=None,
        help="Directory for output file (if not specified, task will look in "
        "{} environment variable, or if none, working directory).".format(
            OUTPUT_DIR_ENV_VAR))
    parser.add_argument('--gui',
                        '-g',
                        action="store_true",
                        help="GUI mode only")
    parser.add_argument('--schema',
                        action="store_true",
                        help="Generate schema picture and stop")
    parser.add_argument(
        "--java",
        default='java',
        help="Java executable (for schema diagrams); default is 'java'")
    parser.add_argument(
        "--plantuml",
        default='plantuml.jar',
        help="PlantUML Java .jar file (for schema diagrams); default "
        "is 'plantuml.jar'")
    parser.add_argument(
        "--schemastem",
        default='schema',
        help="Stem for output filenames (for schema diagrams); default is "
        "'schema'; '.plantuml' and '.png' are appended")
    parser.add_argument(
        "--testtrialplan",
        action="store_true",
        help="Print a test trial plan of the specified sequence length "
        "+/- restrictions")
    parser.add_argument("--seqlen",
                        metavar='SEQUENCE_LEN',
                        type=int,
                        default=None,
                        help="Sequence length for --testtrialplan")
    parser.add_argument(
        "--choice_hole_restriction",
        metavar='CHOICE_HOLE_GROUPS',
        type=ChoiceHoleRestriction,
        help="Optional choice hole restrictions for --testtrialplan; use "
        "e.g. '--choice_hole_restriction \"1,2;3,4\"' to restrict the "
        "choice phase to holes 1 v 2 and 3 v 4")
    parser.add_argument(
        "--serial_pos_restriction",
        metavar='SERIAL_ORDER_POS_GROUPS',
        type=SerialPosRestriction,
        help="Optional choice serial order position restrictions for "
        "--testtrialplan; use e.g. '--serial_pos_restriction "
        "\"1,2;1,3\"' to restrict the choice phase to serial positions "
        "1 v 2 and 1 v 3")
    parser.add_argument(
        "--side_dwor_multiplier",
        metavar="SIDE_DWOR_MULTIPLIER",
        type=int,
        default=1,
        help="Draw-without-replacement (DWOR) multiplier for shuffling on the "
        "basis of whether the left or right side is correct; see docs.")

    # We could allow extra Qt arguments:
    # args, unparsed_args = parser.parse_known_args()
    # Or not:
    args = parser.parse_args()
    unparsed_args = []

    qt_args = sys.argv[:1] + unparsed_args

    # -------------------------------------------------------------------------
    # Modify settings if we're in a PyInstaller bundle
    # -------------------------------------------------------------------------
    in_bundle = getattr(sys, 'frozen', False)
    if in_bundle:
        args.gui = True
    if not args.gui:
        args.guilog = False

    # -------------------------------------------------------------------------
    # Create QApplication before we create any windows (or Qt will crash)
    # -------------------------------------------------------------------------
    qt_app = QApplication(qt_args)

    # -------------------------------------------------------------------------
    # Logging
    # -------------------------------------------------------------------------
    loglevel = logging.DEBUG if args.verbose >= 1 else logging.INFO
    main_only_quicksetup_rootlogger(loglevel)
    logging.getLogger('whisker').setLevel(
        logging.DEBUG if args.verbose >= 2 else logging.INFO)
    if args.logfile:
        copy_root_log_to_file(args.logfile)
    if args.guilog:
        rootlogger = logging.getLogger()
        log_window = LogWindow(level=loglevel,
                               window_title=WINDOW_TITLE + " Python log",
                               logger=rootlogger)
        log_window.show()

    # If any exceptions happen up to this point, we're a bit stuffed.
    # But from now on, we can trap anything and see it in the GUI log, if
    # enabled, even if we have no console.

    # noinspection PyBroadException,PyPep8
    try:

        # ---------------------------------------------------------------------
        # Info
        # ---------------------------------------------------------------------
        log.info("whisker_serial_order v{}: Serial order task for Whisker, "
                 "by Rudolf Cardinal ([email protected])".format(
                     SERIAL_ORDER_VERSION))
        log.debug("args: {}".format(args))
        log.debug("qt_args: {}".format(qt_args))
        log.debug("PyQt version: {}".format(PYQT_VERSION_STR))
        log.debug("QtCore version: {}".format(QT_VERSION_STR))
        log.debug("Whisker client version: {}".format(whisker.version.VERSION))
        if in_bundle:
            log.debug("Running inside a PyInstaller bundle")
        if args.gui:
            log.debug("Running in GUI-only mode")
        # if args.debug_qt_signals:
        #     enable_signal_debugging_simply()

        # ---------------------------------------------------------------------
        # Schema diagram generation only?
        # ---------------------------------------------------------------------
        if args.schema:
            umlfilename = args.schemastem + '.plantuml'
            log.info("Making schema PlantUML: {}".format(umlfilename))
            desc = sadisplay.describe(
                [getattr(models, attr) for attr in dir(models)])
            log.debug(desc)
            with open(umlfilename, 'w') as f:
                f.write(sadisplay.plantuml(desc))
            log.info("Making schema PNG: {}".format(args.schemastem + '.png'))
            cmd = [args.java, '-jar', args.plantuml, umlfilename]
            log.debug(cmd)
            subprocess.check_call(cmd)
            sys.exit(0)

        # ---------------------------------------------------------------------
        # Demo trial plan only?
        # ---------------------------------------------------------------------
        if args.testtrialplan:
            seqlen = args.seqlen
            if seqlen is None or seqlen < MIN_SEQUENCE_LENGTH:
                raise ValueError("--seqlen must be an integer >= {}".format(
                    MIN_SEQUENCE_LENGTH))
            tplist = SerialOrderTask.create_trial_plans(
                seqlen=seqlen,
                choice_hole_restriction=args.choice_hole_restriction,
                serial_pos_restriction=args.serial_pos_restriction,
                side_dwor_multiplier=args.side_dwor_multiplier)
            print("""
Explanation:
- there are 5 holes, numbered 1-5
- sequence: the sequence of hole numbers presented in the trial
    e.g. for a sequence length of 3, you might have sequence=(3, 1, 4),
    meaning that the subject will be shown hole 3, then hole 1, then hole 4,
    in the first phase
- hole_choice: the two holes presented during the choice phase
    e.g. hole_choice=[3,4]
- serial_order_choice: the serial order, in the first phase, of the two holes
    offered in the second (choice) phase -- in this example, you would get
    serial_order_choice=[1,3], because hole 3 was offered in the choice phase
    and was in position 1 in the sequence, and hole 4 was offered in the
    choice phase and was in position 3 in the sequence.
Hint: use grep to check the output.

Choice hole restrictions: {chr}
Serial position restrictions: {spr}
            """.format(
                chr=args.choice_hole_restriction,
                spr=args.serial_pos_restriction,
            ))
            for i, tp in enumerate(tplist, start=1):
                print("{}. {}".format(i, tp))
            sys.exit(0)

        # ---------------------------------------------------------------------
        # File output
        # ---------------------------------------------------------------------
        if args.outdir:
            set_output_directory(args.outdir)
        log.info("Using output directory: {}".format(get_output_directory()))
        if not os.access(get_output_directory(), os.W_OK):
            raise ValueError("Cannot write to output directory")

        # ---------------------------------------------------------------------
        # Database
        # ---------------------------------------------------------------------
        # Get URL, or complain
        if args.dburl:
            set_database_url(args.dburl)
        if args.dbecho:
            set_database_echo(args.dbecho)
        if not dbsettings['url']:
            if args.gui:
                win = NoDatabaseSpecifiedWindow()
                if args.guilog:
                    # noinspection PyUnboundLocalVariable
                    win.exit_kill_log.connect(log_window.exit)
                return run_gui(qt_app, win)
            raise ValueError(MSG_DB_ENV_VAR_NOT_SPECIFIED)
        log.debug("Using database URL: {}".format(dbsettings['url']))
        if database_is_sqlite(dbsettings):
            log.critical(
                "Avoid SQLite: not safe for concurrent use in this context")
            sys.exit(1)

        # Has the user requested a command-line database upgrade?
        if args.upgrade_database:
            sys.exit(
                upgrade_database(ALEMBIC_CONFIG_FILENAME, ALEMBIC_BASE_DIR))
        # Is the database at the correct version?
        (current_revision, head_revision) = get_current_and_head_revision(
            dbsettings['url'], ALEMBIC_CONFIG_FILENAME, ALEMBIC_BASE_DIR)
        if current_revision != head_revision:
            if args.gui:
                win = WrongDatabaseVersionWindow(current_revision,
                                                 head_revision)
                if args.guilog:
                    # noinspection PyUnboundLocalVariable
                    win.exit_kill_log.connect(log_window.exit)
                return run_gui(qt_app, win)
            raise ValueError(
                WRONG_DATABASE_VERSION_STUB.format(
                    head_revision=head_revision,
                    current_revision=current_revision))

        # ---------------------------------------------------------------------
        # Run app
        # ---------------------------------------------------------------------
        log.debug("Seeding random number generator")
        random.seed()
        win = MainWindow(dbsettings)
        if args.guilog:
            # noinspection PyUnboundLocalVariable
            win.exit_kill_log.connect(log_window.exit)
        return run_gui(qt_app, win)

    except:
        if args.guilog:
            log.critical(traceback.format_exc())
            log_window.set_may_close(True)
            return qt_app.exec_()
        else:
            raise
Esempio n. 35
0
def run():
    """Command for reflection database objects"""
    parser = OptionParser(
        version=__version__, description=__doc__,
    )

    parser.add_option(
        '-u', '--url', dest='url',
        help='Database URL (connection string)',
    )

    parser.add_option(
        '-r', '--render', dest='render', default='dot',
        choices=['plantuml', 'dot'],
        help='Output format - plantuml or dot',
    )

    parser.add_option(
        '-l', '--list', dest='list', action='store_true',
        help='Output database list of tables and exit',
    )

    parser.add_option(
        '-i', '--include', dest='include',
        help='List of tables to include through ","',
    )

    parser.add_option(
        '-e', '--exclude', dest='exclude',
        help='List of tables to exlude through ","',
    )

    (options, args) = parser.parse_args()

    if not options.url:
        print('-u/--url option required')
        exit(1)

    engine = create_engine(options.url)
    meta = MetaData()

    meta.reflect(bind=engine)

    if options.list:
        print('Database tables:')
        tables = sorted(meta.tables.keys())

        def _g(l, i):
            try:
                return tables[i]
            except IndexError:
                return ''

        for i in range(0, len(tables), 2):
            print(' {0}{1}{2}'.format(
                _g(tables, i),
                ' ' * (38 - len(_g(tables, i))),
                _g(tables, i + 1),
            ))

        exit(0)

    tables = set(meta.tables.keys())

    if options.include:
        tables &= set(map(string.strip, options.include.split(',')))

    if options.exclude:
        tables -= set(map(string.strip, options.exclude.split(',')))

    desc = describe(map(lambda x: operator.getitem(meta.tables, x), tables))
    print(getattr(render, options.render)(desc))
Esempio n. 36
0
Index("ix_user_title", books.c.user_id, books.c.title)


class Book(object):
    pass


mapper(Book, books, {'user': relation(User, backref='books')})

# Not mapped table
notes = Table(
    'notes',
    BASE.metadata,
    Column('id', Integer, primary_key=True),
    Column('name', Unicode(200), nullable=False),
    Column('user_id', Integer, ForeignKey('user_table.id')),
)

if __name__ == '__main__':
    import codecs
    import sadisplay

    desc = sadisplay.describe(globals().values())

    with codecs.open('/tmp/schema.plantuml', 'w', encoding='utf-8') as f:
        f.write(sadisplay.plantuml(desc))

    with codecs.open('/tmp/schema.dot', 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc))
Esempio n. 37
0
 def __generate_graphviz_dot_file_content(self, db_models) -> str:
     desc = sadisplay.describe(db_models,
                               show_indexes=self.__show_indexes,
                               show_methods=self.__show_active_components,
                               show_properties=self.__show_active_components)
     return sadisplay.dot(desc)
Esempio n. 38
0
import sadisplay
from ws import schema

desc = sadisplay.describe([getattr(schema, attr) for attr in dir(schema)])
open('schema.dot', 'w').write(sadisplay.dot(desc))
Esempio n. 39
0
    import sadisplay

    from niamoto.db import metadata

    PROJECT_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
    dot_destination_path = os.path.join(
        PROJECT_PATH,
        "docs",
        "_static",
        "db_schema.dot",
    )
    if len(sys.argv) > 1:
        dot_destination_path = sys.argv[1]

    desc = sadisplay.describe(
        [getattr(metadata, attr) for attr in dir(metadata)], )
    with open(dot_destination_path, 'w', encoding='utf-8') as f:
        f.write(sadisplay.dot(desc, ))

    svg_destination_path = os.path.join(
        PROJECT_PATH,
        "docs",
        "_static",
        "db_schema.svg",
    )

    if len(sys.argv) > 2:
        svg_destination_path = sys.argv[2]

    with open(svg_destination_path, 'w') as f:
        subprocess.Popen(["dot", "-Tsvg", dot_destination_path], stdout=f)
Esempio n. 40
0
#!/usr/bin/env python
import sys

import sadisplay
from irdata import model

if __name__ == '__main__':
    outfile = sys.argv[1]
    desc = sadisplay.describe([getattr(model, attr) for attr in dir(model)])
    open(outfile, 'w').write(sadisplay.dot(desc))

Esempio n. 41
0
)


class Book(object):
    pass


mapper(Book, books, {'user': relation(User, backref='books')})


# Not mapped table
notes = Table(
    'notes',
    BASE.metadata,
    Column('id', Integer, primary_key=True),
    Column('name', Unicode(200), nullable=False),
    Column('user_id', Integer, ForeignKey('user_table.id')),
)


if __name__ == '__main__':
    import sadisplay

    desc = sadisplay.describe(globals().values())

    with open('schema.plantuml', 'w') as f:
        f.write(sadisplay.plantuml(desc))

    with open('schema.dot', 'w') as f:
        f.write(sadisplay.dot(desc))
Esempio n. 42
0
#-*- coding:utf-8 -*-
import sadisplay
from app import models

desc = sadisplay.describe([models.User,models.Question,models.Answer,models.Role,models.Tag,models.Follow,models.Vote, models.Unvote,models.assoc_question_tag_table])
file = open('schema.dot', 'w')
file.write(sadisplay.dot(desc).encode('utf-8'))
file.close()
Esempio n. 43
0
import sadisplay
from app import models
import os

desc = sadisplay.describe([models.Survey, models.Consent,models.Section,models.Question, models.Condition, models.User, models.StateSurvey,models.Answer])
open('schema1_alto_nivel.dot', 'w').write(sadisplay.dot(desc))
os.system("dot -Tsvg schema1_alto_nivel.dot > schema1_alto_nivel.svg")

#esquema preguntas:
desc = sadisplay.describe([models.Question,models.QuestionText,models.QuestionYN, models.QuestionChoice, models.QuestionLikertScale])
open('preguntas.dot', 'w').write(sadisplay.dot(desc))
os.system("dot -Tsvg preguntas.dot > preguntas.svg")

#esquema juegos:


desc = sadisplay.describe([models.GameImpatience, models.Game, models.Raffle, models.User, models.Survey])
open('games_sin_detalle.dot', 'w').write(sadisplay.dot(desc))
os.system("dot -Tsvg games_sin_detalle.dot > games_sin_detalle.svg")

desc = sadisplay.describe([models.Game, models.GameLottery1, models.GameLottery2, models.GameRent1, models.GameRent2, models.GameUltimatum, models.GameDictador])
open('games.dot', 'w').write(sadisplay.dot(desc))
os.system("dot -Tsvg games.dot > games.svg")

#esquema base de datos
os.system("sadisplay -u sqlite:////home/jarenere/frame_game_theory_esquemas/data-dev.sqlite -i answer,condition,consent,question,section,stateSurvey,survey,user -r dot > schema_bbdd.dot")
os.system("dot -Tsvg schema_bbdd.dot > schema_bbdd.svg")

os.system("sadisplay -u sqlite:////home/jarenere/frame_game_theory_esquemas/data-dev.sqlite -i answer,user,raffle,game,gameImpatience,survey -r dot > schema_bbdd_game.dot")
os.system("dot -Tsvg schema_bbdd_game.dot > schema_bbdd_game.svg")