Package gensaschema :: Module _constraint
[frames] | no frames]

Source Code for Module gensaschema._constraint

  1  # -*- coding: ascii -*- 
  2  r""" 
  3  ========================================== 
  4   Constraint inspection and representation 
  5  ========================================== 
  6   
  7  Constraint inspection and representation. 
  8   
  9  :Copyright: 
 10   
 11   Copyright 2010 - 2016 
 12   Andr\xe9 Malo or his licensors, as applicable 
 13   
 14  :License: 
 15   
 16   Licensed under the Apache License, Version 2.0 (the "License"); 
 17   you may not use this file except in compliance with the License. 
 18   You may obtain a copy of the License at 
 19   
 20       http://www.apache.org/licenses/LICENSE-2.0 
 21   
 22   Unless required by applicable law or agreed to in writing, software 
 23   distributed under the License is distributed on an "AS IS" BASIS, 
 24   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 25   See the License for the specific language governing permissions and 
 26   limitations under the License. 
 27   
 28  """ 
 29  if __doc__: 
 30      # pylint: disable = redefined-builtin 
 31      __doc__ = __doc__.encode('ascii').decode('unicode_escape') 
 32  __author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape') 
 33  __docformat__ = "restructuredtext en" 
 34   
 35  import keyword as _keyword 
 36  import re as _re 
 37  import tokenize as _tokenize 
 38   
 39  from . import _util 
 40   
 41   
42 -class Constraint(object):
43 """ 44 Reflected Constraint 45 46 :IVariables: 47 `constraint` : SA Constraint 48 Constraint 49 """ 50 _SYMBOL, _IMPORT = None, None 51
52 - def __new__(cls, constraint, table, symbols, options=None):
53 """ Constraint factory """ 54 if cls == Constraint: 55 name = constraint.__class__.__name__ 56 if name == 'CheckConstraint': 57 return None 58 return globals()[name]( 59 constraint, table, symbols, options=options 60 ) 61 return object.__new__(cls)
62
63 - def __init__(self, constraint, table, symbols, options=None):
64 """ 65 Initialization 66 67 :Parameters: 68 `constraint` : SA Constraint 69 Constraint 70 71 `table` : ``str`` 72 Table varname 73 """ 74 self.constraint = constraint 75 self.table = table 76 self._symbols = symbols 77 self._symbols.imports[self._SYMBOL] = self._IMPORT 78 self.options = options
79
80 - def copy(self):
81 """ Create shallow copy """ 82 return self.__class__( 83 self.constraint, self.table, self._symbols, self.options 84 )
85
86 - def __cmp__(self, other):
87 """ Compare """ 88 names = [ 89 'PrimaryKeyConstraint', 'UniqueConstraint', 90 'ForeignKeyConstraint', 'CheckConstraint' 91 ] 92 93 def bytype(const): 94 """ Sort by type """ 95 try: 96 return names.index(const.__class__.__name__) 97 except IndexError: 98 return -1
99 100 return cmp(( 101 bytype(self.constraint), 102 self.options is not None, 103 self.constraint.name, 104 ), ( 105 bytype(other.constraint), 106 other.options is not None, 107 other.constraint.name, 108 ))
109
110 - def repr(self, symbol, args, keywords=(), short=False):
111 """ 112 Base repr for all constraints 113 114 :Parameters: 115 `args` : iterable 116 Positional arguments 117 118 :Return: The constraint repr 119 :Rtype: ``str`` 120 """ 121 # pylint: disable = R0912 122 # (too many branches) 123 124 params = [] 125 if self.constraint.name is not None: 126 params.append('name=%r' % (self.constraint.name,)) 127 if self.constraint.deferrable is not None: 128 params.append('deferrable=%r' % (self.constraint.deferrable,)) 129 if self.constraint.initially is not None: 130 params.append('initially=%r' % (self.constraint.initially,)) 131 for keyword in keywords: 132 if getattr(self.constraint, keyword) is not None: 133 params.append("%s=%r" % ( 134 keyword, getattr(self.constraint, keyword) 135 )) 136 if short and len(params) > 1: 137 short = False 138 if args: 139 if short: 140 args = ', '.join(args) 141 else: 142 args = '\n ' + ',\n '.join(args) + ',' 143 else: 144 args = '' 145 146 if short: 147 params = ', '.join(params) 148 if args and params: 149 params = ', ' + params 150 else: 151 params = ',\n '.join(params) 152 if params: 153 params = '\n ' + params + ',' 154 if args or params: 155 params += '\n' 156 157 return "%s(%s%s)" % (self._symbols[symbol], args, params)
158 159
160 -def access_col(col):
161 """ 162 Generate column access string (either as attribute or via dict access) 163 164 :Parameters: 165 `col` : SA Column 166 Column 167 168 :Return: Access string 169 :Rtype: ``str`` 170 """ 171 try: 172 name = col.name 173 except AttributeError: 174 name = col 175 try: 176 if _util.py2 and isinstance(name, _util.bytes): 177 name.decode('ascii') 178 else: 179 name.encode('ascii') 180 except UnicodeError: 181 is_ascii = False 182 else: 183 is_ascii = True 184 if is_ascii and not _keyword.iskeyword(name) and \ 185 _re.match(_tokenize.Name + '$', name): 186 return ".c.%s" % name 187 return ".c[%r]" % name
188 189
190 -class UniqueConstraint(Constraint):
191 """ Unique constraint """ 192 _SYMBOL = 'uk' 193 _IMPORT = 'from %(constraints)s import Unique as %(uk)s' 194
195 - def __repr__(self):
196 """ 197 Make string representation 198 199 :Return: The string representation 200 :Rtype: ``str`` 201 """ 202 empty = len(self.constraint.columns) == 0 203 short = len(self.constraint.columns) <= 1 204 result = self.repr(self._SYMBOL, [ 205 "%s%s" % (self.table, access_col(col)) 206 for col in self.constraint.columns 207 ], short=short) 208 if empty: 209 result = "# %s" % result 210 return result
211 212
213 -class PrimaryKeyConstraint(UniqueConstraint):
214 """ Primary Key constraint """ 215 _SYMBOL = 'pk' 216 _IMPORT = 'from %(constraints)s import PrimaryKey as %(pk)s'
217 218
219 -class ForeignKeyConstraint(Constraint):
220 """ ForeignKey constraint """ 221 _SYMBOL = 'fk' 222 _IMPORT = 'from %(constraints)s import ForeignKey as %(fk)s' 223
224 - def __repr__(self):
225 """ 226 Make string representation 227 228 :Return: The string representation 229 :Rtype: ``str`` 230 """ 231 columns = "[%s]" % ',\n '.join([ 232 "%s%s" % (self.table, access_col(col)) 233 for col in self.constraint.columns 234 ]) 235 refcolumns = "[%s]" % ',\n '.join(["%s%s" % ( 236 self._symbols[u'table_%s' % key.column.table.name], 237 access_col(key.column), 238 ) for key in self.constraint.elements]) 239 keywords = ['onupdate', 'ondelete'] 240 if self.constraint.use_alter: 241 keywords.append('use_alter') 242 result = self.repr('fk', [columns, refcolumns], keywords) 243 244 if self.options: 245 cyclic = self.constraint.use_alter 246 if self.options.startswith('seen:'): 247 table = self.options.split(None, 1)[1] 248 if cyclic: 249 result = '\n# Cyclic foreign key:\n' + result 250 else: 251 result = '\n# Foreign key belongs to %r:\n%s' % ( 252 table, result 253 ) 254 elif self.options.startswith('unseen:'): 255 table = self.options.split(None, 1)[1] 256 result = result.splitlines(True) 257 if cyclic: 258 result.insert( 259 0, 260 'Cyclic foreign key, defined at table %r:\n' % table 261 ) 262 else: 263 result.insert(0, 'Defined at table %r:\n' % table) 264 result = '\n' + ''.join(['# %s' % item for item in result]) 265 266 return result
267