Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import re 

2 

3from .impl import DefaultImpl 

4from .. import util 

5 

6 

7class SQLiteImpl(DefaultImpl): 

8 __dialect__ = "sqlite" 

9 

10 transactional_ddl = False 

11 """SQLite supports transactional DDL, but pysqlite does not: 

12 see: http://bugs.python.org/issue10740 

13 """ 

14 

15 def requires_recreate_in_batch(self, batch_op): 

16 """Return True if the given :class:`.BatchOperationsImpl` 

17 would need the table to be recreated and copied in order to 

18 proceed. 

19 

20 Normally, only returns True on SQLite when operations other 

21 than add_column are present. 

22 

23 """ 

24 for op in batch_op.batch: 

25 if op[0] not in ("add_column", "create_index", "drop_index"): 

26 return True 

27 else: 

28 return False 

29 

30 def add_constraint(self, const): 

31 # attempt to distinguish between an 

32 # auto-gen constraint and an explicit one 

33 if const._create_rule is None: 

34 raise NotImplementedError( 

35 "No support for ALTER of constraints in SQLite dialect" 

36 "Please refer to the batch mode feature which allows for " 

37 "SQLite migrations using a copy-and-move strategy." 

38 ) 

39 elif const._create_rule(self): 

40 util.warn( 

41 "Skipping unsupported ALTER for " 

42 "creation of implicit constraint" 

43 "Please refer to the batch mode feature which allows for " 

44 "SQLite migrations using a copy-and-move strategy." 

45 ) 

46 

47 def drop_constraint(self, const): 

48 if const._create_rule is None: 

49 raise NotImplementedError( 

50 "No support for ALTER of constraints in SQLite dialect" 

51 "Please refer to the batch mode feature which allows for " 

52 "SQLite migrations using a copy-and-move strategy." 

53 ) 

54 

55 def compare_server_default( 

56 self, 

57 inspector_column, 

58 metadata_column, 

59 rendered_metadata_default, 

60 rendered_inspector_default, 

61 ): 

62 

63 if rendered_metadata_default is not None: 

64 rendered_metadata_default = re.sub( 

65 r"^\((.+)\)$", r"\1", rendered_metadata_default 

66 ) 

67 

68 rendered_metadata_default = re.sub( 

69 r"^\"?'(.+)'\"?$", r"\1", rendered_metadata_default 

70 ) 

71 

72 if rendered_inspector_default is not None: 

73 rendered_inspector_default = re.sub( 

74 r"^\"?'(.+)'\"?$", r"\1", rendered_inspector_default 

75 ) 

76 

77 return rendered_inspector_default != rendered_metadata_default 

78 

79 def _guess_if_default_is_unparenthesized_sql_expr(self, expr): 

80 """Determine if a server default is a SQL expression or a constant. 

81 

82 There are too many assertions that expect server defaults to round-trip 

83 identically without parenthesis added so we will add parens only in 

84 very specific cases. 

85 

86 """ 

87 if not expr: 

88 return False 

89 elif re.match(r"^[0-9\.]$", expr): 

90 return False 

91 elif re.match(r"^'.+'$", expr): 

92 return False 

93 elif re.match(r"^\(.+\)$", expr): 

94 return False 

95 else: 

96 return True 

97 

98 def autogen_column_reflect(self, inspector, table, column_info): 

99 # SQLite expression defaults require parenthesis when sent 

100 # as DDL 

101 if self._guess_if_default_is_unparenthesized_sql_expr( 

102 column_info.get("default", None) 

103 ): 

104 column_info["default"] = "(%s)" % (column_info["default"],) 

105 

106 def render_ddl_sql_expr(self, expr, is_server_default=False, **kw): 

107 # SQLite expression defaults require parenthesis when sent 

108 # as DDL 

109 str_expr = super(SQLiteImpl, self).render_ddl_sql_expr( 

110 expr, is_server_default=is_server_default, **kw 

111 ) 

112 

113 if ( 

114 is_server_default 

115 and self._guess_if_default_is_unparenthesized_sql_expr(str_expr) 

116 ): 

117 str_expr = "(%s)" % (str_expr,) 

118 return str_expr 

119 

120 

121# @compiles(AddColumn, 'sqlite') 

122# def visit_add_column(element, compiler, **kw): 

123# return "%s %s" % ( 

124# alter_table(compiler, element.table_name, element.schema), 

125# add_column(compiler, element.column, **kw) 

126# ) 

127 

128 

129# def add_column(compiler, column, **kw): 

130# text = "ADD COLUMN %s" % compiler.get_column_specification(column, **kw) 

131# need to modify SQLAlchemy so that the CHECK associated with a Boolean 

132# or Enum gets placed as part of the column constraints, not the Table 

133# see ticket 98 

134# for const in column.constraints: 

135# text += compiler.process(AddConstraint(const)) 

136# return text