Skip to content

Commit 309133d

Browse files
authored
Merge pull request #11 from con-av/master
merged in latest version (1.1.6) of parent repo
2 parents d778b92 + b22208a commit 309133d

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

sqlacodegen/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = '1.1.5.pre2'
1+
version = __version__ = '1.1.6'

sqlacodegen/codegen.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ def plural_noun(self, noun): # needed for backrefs
4141
return inflect_engine.plural_noun(noun)
4242

4343

44+
# In SQLAlchemy 0.x, constraint.columns is sometimes a list, on 1.x onwards, always a ColumnCollection
45+
def _get_column_names(constraint):
46+
if isinstance(constraint.columns, list):
47+
return constraint.columns
48+
return list(constraint.columns.keys())
49+
50+
4451
def _convert_to_valid_identifier(name):
4552
assert name, 'Identifier cannot be empty'
4653
if name[0].isdigit() or iskeyword(name):
@@ -71,7 +78,7 @@ def visit_bindparam(self, bindparam, within_columns_clause=False, literal_binds=
7178
def _get_constraint_sort_key(constraint):
7279
if isinstance(constraint, CheckConstraint):
7380
return 'C{0}'.format(constraint.sqltext)
74-
return constraint.__class__.__name__[0] + repr(constraint.columns)
81+
return constraint.__class__.__name__[0] + repr(_get_column_names(constraint))
7582

7683

7784
def _get_common_fk_constraints(table1, table2):
@@ -177,7 +184,7 @@ def render_fk_options(*opts):
177184
remote_column = '{0}.{1}'.format(constraint.column.table.fullname, constraint.column.name)
178185
return _flask_prepend + 'ForeignKey({0})'.format(render_fk_options(remote_column))
179186
elif isinstance(constraint, ForeignKeyConstraint):
180-
local_columns = constraint.columns
187+
local_columns = _get_column_names(constraint)
181188
remote_columns = ['{0}.{1}'.format(fk.column.table.fullname, fk.column.name)
182189
for fk in constraint.elements]
183190
return _flask_prepend + 'ForeignKeyConstraint({0})'.format(render_fk_options(local_columns, remote_columns))
@@ -313,7 +320,8 @@ def __init__(self, table, association_tables, inflect_engine, detect_joined):
313320
for constraint in sorted(table.constraints, key=_get_constraint_sort_key):
314321
if isinstance(constraint, ForeignKeyConstraint):
315322
target_cls = self._tablename_to_classname(constraint.elements[0].column.table.name, inflect_engine)
316-
if detect_joined and self.parent_name == 'Base' and set(constraint.columns) == pk_column_names:
323+
if (detect_joined and self.parent_name == 'Base' and
324+
set(_get_column_names(constraint)) == pk_column_names):
317325
self.parent_name = target_cls
318326
else:
319327
relationship_ = ManyToOneRelationship(self.name, target_cls, constraint, inflect_engine)
@@ -452,7 +460,8 @@ class ManyToOneRelationship(Relationship):
452460
def __init__(self, source_cls, target_cls, constraint, inflect_engine):
453461
super(ManyToOneRelationship, self).__init__(source_cls, target_cls)
454462

455-
colname = constraint.columns[0]
463+
column_names = _get_column_names(constraint)
464+
colname = column_names[0]
456465
tablename = constraint.elements[0].column.table.name
457466
if not colname.endswith('_id'):
458467
self.preferred_name = inflect_engine.singular_noun(tablename) or tablename
@@ -462,7 +471,7 @@ def __init__(self, source_cls, target_cls, constraint, inflect_engine):
462471

463472
# Add uselist=False to One-to-One relationships
464473
if any(isinstance(c, (PrimaryKeyConstraint, UniqueConstraint)) and
465-
set(col.name for col in c.columns) == set(constraint.columns)
474+
set(col.name for col in c.columns) == set(column_names)
466475
for c in constraint.table.constraints):
467476
self.kwargs['uselist'] = 'False'
468477

@@ -481,7 +490,7 @@ def __init__(self, source_cls, target_cls, constraint, inflect_engine):
481490
self.kwargs['primaryjoin'] = "'and_({0})'".format(', '.join(['{0}.{1} == {2}.{3}'.format(source_cls, k.parent.name, target_cls, k.column.name)
482491
for k in constraint.elements]))
483492
else:
484-
self.kwargs['primaryjoin'] = "'{0}.{1} == {2}.{3}'".format(source_cls, constraint.columns[0], target_cls,
493+
self.kwargs['primaryjoin'] = "'{0}.{1} == {2}.{3}'".format(source_cls, column_names[0], target_cls,
485494
constraint.elements[0].column.name)
486495

487496

@@ -492,16 +501,16 @@ def __init__(self, source_cls, target_cls, assocation_table, inflect_engine):
492501
self.kwargs['secondary'] = repr(assocation_table.schema + '.' + assocation_table.name)
493502
constraints = [c for c in assocation_table.constraints if isinstance(c, ForeignKeyConstraint)]
494503
constraints.sort(key=_get_constraint_sort_key)
495-
colname = constraints[1].columns[0]
504+
colname = _get_column_names(constraints[1])[0]
496505
tablename = constraints[1].elements[0].column.table.name
497506
self.preferred_name = tablename if not colname.endswith('_id') else colname[:-3] + 's'
498507
self.backref_name = inflect_engine.plural_noun(self.backref_name)
499508

500509
# Handle self referential relationships
501510
if source_cls == target_cls:
502511
self.preferred_name = 'parents' if not colname.endswith('_id') else colname[:-3] + 's'
503-
pri_pairs = zip(constraints[0].columns, constraints[0].elements)
504-
sec_pairs = zip(constraints[1].columns, constraints[1].elements)
512+
pri_pairs = zip(_get_column_names(constraints[0]), constraints[0].elements)
513+
sec_pairs = zip(_get_column_names(constraints[1]), constraints[1].elements)
505514
pri_joins = ['{0}.{1} == {2}.c.{3}'.format(source_cls, elem.column.name, assocation_table.name, col)
506515
for col, elem in pri_pairs]
507516
sec_joins = ['{0}.{1} == {2}.c.{3}'.format(target_cls, elem.column.name, assocation_table.name, col)

sqlacodegen/main.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
""" """
22
from __future__ import unicode_literals, division, print_function, absolute_import
33
import argparse
4+
import codecs
45
import importlib
56
import sys
67

@@ -31,11 +32,13 @@ def main():
3132
parser.add_argument('--noconstraints', action='store_true', help='ignore constraints')
3233
parser.add_argument('--nojoined', action='store_true', help="don't autodetect joined table inheritance")
3334
parser.add_argument('--noinflect', action='store_true', help="don't try to convert tables names to singular form")
35+
parser.add_argument('--noclasses', action='store_true', help="don't generate classes, only tables")
36+
parser.add_argument('--outfile', help='file to write output to (default: stdout)')
3437
parser.add_argument('--nobackrefs', action='store_true', help="don't include backrefs")
3538
parser.add_argument('--flask', action='store_true', help="use Flask-SQLAlchemy columns")
3639
parser.add_argument('--ignorefk', help="Don't check fk constraints on specified columns (comma-separated)")
37-
parser.add_argument('--outfile', type=argparse.FileType('w'), default=sys.stdout,
38-
help='file to write output to (default: stdout)')
40+
# parser.add_argument('--outfile', type=argparse.FileType('w'), default=sys.stdout,
41+
# help='file to write output to (default: stdout)')
3942
args = parser.parse_args()
4043

4144
if args.version:
@@ -52,7 +55,8 @@ def main():
5255
tables = args.tables.split(',') if args.tables else None
5356
fkcols = args.ignorefk.split(',') if args.ignorefk else None
5457
metadata.reflect(engine, args.schema, not args.noviews, tables)
58+
outfile = codecs.open(args.outfile, 'w', encoding='utf-8') if args.outfile else sys.stdout
5559
generator = CodeGenerator(metadata, args.noindexes, args.noconstraints,
5660
args.nojoined, args.noinflect, args.nobackrefs,
5761
args.flask, fkcols)
58-
generator.render(args.outfile)
62+
generator.render(outfile)

0 commit comments

Comments
 (0)