PageRenderTime 48ms CodeModel.GetById 13ms app.highlight 29ms RepoModel.GetById 2ms app.codeStats 0ms

/sqlautocode/config.py

https://code.google.com/p/sqlautocode/
Python | 189 lines | 179 code | 4 blank | 6 comment | 9 complexity | a012232eaa45ab8b0024c8d35504cd04 MD5 | raw file
  1#!python
  2#-*- coding: UTF-8 -*-
  3
  4import optparse
  5import os
  6import sys
  7import re
  8
  9options = None
 10out = sys.stdout
 11err = sys.stderr
 12dburl  = None
 13engine = None
 14
 15# TODO: encoding (default utf-8)
 16
 17def create_parser():
 18    parser = optparse.OptionParser(
 19        """autocode.py <database_url> [options, ]
 20Generates Python source code for a given database schema.
 21
 22Example: ./autocode.py postgres://user:password@myhost/database -o out.py""")
 23
 24    parser.add_option(
 25        "-o", "--output",
 26        help="Write to file (default is stdout)",
 27        action="store", dest="output")
 28
 29    parser.add_option(
 30        "--force",
 31        help="Overwrite Write to file (default is stdout)",
 32        action="store_true", dest="force")
 33
 34    parser.add_option(
 35        "-s", "--schema",
 36        help="Optional, reflect a non-default schema",
 37        action="callback", callback=_prep_schema, type="string", dest="schema")
 38
 39    parser.add_option(
 40        "-t", "--tables",
 41        help=("Optional, only reflect this comma-separated list of tables. "
 42              "Wildcarding with '*' is supported, e.g: --tables account_*,"
 43              "orders,order_items,*_audit"),
 44        action="callback", callback=_prep_tables, type="string", dest="tables")
 45
 46    parser.add_option(
 47        "-b", "--table-prefix",
 48        help="Prefix for generated SQLAlchemy Table object names",
 49        action="store", dest="table_prefix")
 50
 51    parser.add_option(
 52        "-a", "--table-suffix",
 53        help="Suffix for generated SQLAlchemy Table object names",
 54        action="store", dest="table_suffix")
 55
 56    parser.add_option(
 57        "-i", "--noindexes", "--noindex",
 58        help="Do not emit index information",
 59        action="store_true", dest="noindex")
 60
 61    parser.add_option(
 62        "-g", "--generic-types",
 63        help="Emit generic ANSI column types instead of database-specific.",
 64        action="store_true", dest="generictypes")
 65
 66    parser.add_option(
 67        "--encoding",
 68        help="Encoding for output, default utf8",
 69        action="store", dest="encoding")
 70
 71    parser.add_option(
 72        "-e", "--example",
 73        help="Generate code with examples how to access data",
 74        action="store_true", dest="example")
 75
 76    parser.add_option(
 77        "-3", "--z3c",
 78        help="Generate code for use with z3c.sqlalchemy",
 79        action="store_true", dest="z3c")
 80
 81    parser.add_option(
 82        "-d", "--declarative",
 83        help="Generate declarative SA code",
 84        action="store_true", dest="declarative")
 85    
 86    parser.add_option(
 87        "-n", "--interactive",
 88        help="Generate Interactive example in your code.",
 89        action="store_true", dest="interactive")
 90
 91
 92    parser.set_defaults(tables=[],
 93                        encoding='utf-8',
 94                        table_prefix='',
 95                        table_suffix='')
 96
 97    return parser
 98
 99def _prep_tables(option, opt_str, value, parser):
100    if not value:
101        parser.values.tables = []
102    else:
103        parser.values.tables = [x.strip()
104                                for x in value.split(',')
105                                if x.strip() != '']
106
107def _prep_schema(option, opt_str, value, parser):
108    #handle multiple schemas on the command line
109    value = [x.strip()
110                for x in value.split(',')
111                if x.strip() != '']
112    if len(value) == 1:
113        parser.values.schema = value[0]
114        return
115    parser.values.schema = value
116
117def _version_check(parser):
118    try:
119        import sqlalchemy
120    except ImportError, ex:
121        parser.error("SQLAlchemy version 0.4.0 or higher is required. (%s)" %
122                     (ex))
123
124    version = getattr(sqlalchemy, '__version__', None)
125    if version is None:
126        parser.error("SQLAlchemy version 0.4.0 or higher is required.")
127    elif version == 'svn':
128        pass
129    else:
130        non_numeric = re.compile('[^0-9]*')
131        version_info = tuple([int(i) for i in non_numeric.split(version)])
132        if version_info < (0, 4):
133            parser.error("SQLAlchemy version 0.4.0 or higher is required.")
134
135def _setup_engine(parser, url):
136    global engine
137
138    import sqlalchemy
139    try:
140        engine = sqlalchemy.create_engine(url)
141        test = engine.connect()
142        test.close()
143    except sqlalchemy.exceptions.SQLAlchemyError, ex:
144        parser.error('Could not connect to "%s": %s' % (url, ex))
145
146
147def _instrument():
148    # monkeypatch SQLAlchemy __repr__ methods
149    import formatter
150    import loader
151
152def _set_output(path, overwrite=False):
153    if os.path.exists(path) and not overwrite:
154        print >>err, 'File "%s" exists and will be overwritten.' % path
155        resp = raw_input('Overwrite (y/[n]): ')
156        if not resp.strip().lower().startswith('y'):
157            print >>err, "Aborted."
158            sys.exit(-1)
159
160    global out
161    try:
162        out = open(path, 'w')
163    except IOError, e:
164        print >>err, 'Could not open "%s" for writing: %s' % (path, e)
165        sys.exit(-1)
166
167
168def configure(argv=sys.argv):
169    global options, dburl
170
171    parser = create_parser()
172    options, args = parser.parse_args(argv)
173
174    if len(args) < 2:
175        parser.error("A database URL is required.")
176    elif len(args) > 2:
177        parser.error("Unknown arguments: %s" % (' '.join(args[2:])))
178    else:
179        dburl = args[1]
180
181    _version_check(parser)
182
183    _setup_engine(parser, dburl)
184
185    _instrument()
186    
187    if options.output is not None:
188        _set_output(options.output, options.force)
189