information_schema.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. # mssql/information_schema.py
  2. # Copyright (C) 2005-2022 the SQLAlchemy authors and contributors
  3. # <see AUTHORS file>
  4. #
  5. # This module is part of SQLAlchemy and is released under
  6. # the MIT License: https://www.opensource.org/licenses/mit-license.php
  7. from ... import cast
  8. from ... import Column
  9. from ... import MetaData
  10. from ... import Table
  11. from ... import util
  12. from ...ext.compiler import compiles
  13. from ...sql import expression
  14. from ...types import Boolean
  15. from ...types import Integer
  16. from ...types import Numeric
  17. from ...types import String
  18. from ...types import TypeDecorator
  19. from ...types import Unicode
  20. ischema = MetaData()
  21. class CoerceUnicode(TypeDecorator):
  22. impl = Unicode
  23. cache_ok = True
  24. def process_bind_param(self, value, dialect):
  25. if util.py2k and isinstance(value, util.binary_type):
  26. value = value.decode(dialect.encoding)
  27. return value
  28. def bind_expression(self, bindvalue):
  29. return _cast_on_2005(bindvalue)
  30. class _cast_on_2005(expression.ColumnElement):
  31. def __init__(self, bindvalue):
  32. self.bindvalue = bindvalue
  33. @compiles(_cast_on_2005)
  34. def _compile(element, compiler, **kw):
  35. from . import base
  36. if (
  37. compiler.dialect.server_version_info is None
  38. or compiler.dialect.server_version_info < base.MS_2005_VERSION
  39. ):
  40. return compiler.process(element.bindvalue, **kw)
  41. else:
  42. return compiler.process(cast(element.bindvalue, Unicode), **kw)
  43. schemata = Table(
  44. "SCHEMATA",
  45. ischema,
  46. Column("CATALOG_NAME", CoerceUnicode, key="catalog_name"),
  47. Column("SCHEMA_NAME", CoerceUnicode, key="schema_name"),
  48. Column("SCHEMA_OWNER", CoerceUnicode, key="schema_owner"),
  49. schema="INFORMATION_SCHEMA",
  50. )
  51. tables = Table(
  52. "TABLES",
  53. ischema,
  54. Column("TABLE_CATALOG", CoerceUnicode, key="table_catalog"),
  55. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  56. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  57. Column("TABLE_TYPE", CoerceUnicode, key="table_type"),
  58. schema="INFORMATION_SCHEMA",
  59. )
  60. columns = Table(
  61. "COLUMNS",
  62. ischema,
  63. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  64. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  65. Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
  66. Column("IS_NULLABLE", Integer, key="is_nullable"),
  67. Column("DATA_TYPE", String, key="data_type"),
  68. Column("ORDINAL_POSITION", Integer, key="ordinal_position"),
  69. Column(
  70. "CHARACTER_MAXIMUM_LENGTH", Integer, key="character_maximum_length"
  71. ),
  72. Column("NUMERIC_PRECISION", Integer, key="numeric_precision"),
  73. Column("NUMERIC_SCALE", Integer, key="numeric_scale"),
  74. Column("COLUMN_DEFAULT", Integer, key="column_default"),
  75. Column("COLLATION_NAME", String, key="collation_name"),
  76. schema="INFORMATION_SCHEMA",
  77. )
  78. mssql_temp_table_columns = Table(
  79. "COLUMNS",
  80. ischema,
  81. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  82. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  83. Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
  84. Column("IS_NULLABLE", Integer, key="is_nullable"),
  85. Column("DATA_TYPE", String, key="data_type"),
  86. Column("ORDINAL_POSITION", Integer, key="ordinal_position"),
  87. Column(
  88. "CHARACTER_MAXIMUM_LENGTH", Integer, key="character_maximum_length"
  89. ),
  90. Column("NUMERIC_PRECISION", Integer, key="numeric_precision"),
  91. Column("NUMERIC_SCALE", Integer, key="numeric_scale"),
  92. Column("COLUMN_DEFAULT", Integer, key="column_default"),
  93. Column("COLLATION_NAME", String, key="collation_name"),
  94. schema="tempdb.INFORMATION_SCHEMA",
  95. )
  96. constraints = Table(
  97. "TABLE_CONSTRAINTS",
  98. ischema,
  99. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  100. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  101. Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
  102. Column("CONSTRAINT_TYPE", CoerceUnicode, key="constraint_type"),
  103. schema="INFORMATION_SCHEMA",
  104. )
  105. column_constraints = Table(
  106. "CONSTRAINT_COLUMN_USAGE",
  107. ischema,
  108. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  109. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  110. Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
  111. Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
  112. schema="INFORMATION_SCHEMA",
  113. )
  114. key_constraints = Table(
  115. "KEY_COLUMN_USAGE",
  116. ischema,
  117. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  118. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  119. Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
  120. Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
  121. Column("CONSTRAINT_SCHEMA", CoerceUnicode, key="constraint_schema"),
  122. Column("ORDINAL_POSITION", Integer, key="ordinal_position"),
  123. schema="INFORMATION_SCHEMA",
  124. )
  125. ref_constraints = Table(
  126. "REFERENTIAL_CONSTRAINTS",
  127. ischema,
  128. Column("CONSTRAINT_CATALOG", CoerceUnicode, key="constraint_catalog"),
  129. Column("CONSTRAINT_SCHEMA", CoerceUnicode, key="constraint_schema"),
  130. Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
  131. # TODO: is CATLOG misspelled ?
  132. Column(
  133. "UNIQUE_CONSTRAINT_CATLOG",
  134. CoerceUnicode,
  135. key="unique_constraint_catalog",
  136. ),
  137. Column(
  138. "UNIQUE_CONSTRAINT_SCHEMA",
  139. CoerceUnicode,
  140. key="unique_constraint_schema",
  141. ),
  142. Column(
  143. "UNIQUE_CONSTRAINT_NAME", CoerceUnicode, key="unique_constraint_name"
  144. ),
  145. Column("MATCH_OPTION", String, key="match_option"),
  146. Column("UPDATE_RULE", String, key="update_rule"),
  147. Column("DELETE_RULE", String, key="delete_rule"),
  148. schema="INFORMATION_SCHEMA",
  149. )
  150. views = Table(
  151. "VIEWS",
  152. ischema,
  153. Column("TABLE_CATALOG", CoerceUnicode, key="table_catalog"),
  154. Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
  155. Column("TABLE_NAME", CoerceUnicode, key="table_name"),
  156. Column("VIEW_DEFINITION", CoerceUnicode, key="view_definition"),
  157. Column("CHECK_OPTION", String, key="check_option"),
  158. Column("IS_UPDATABLE", String, key="is_updatable"),
  159. schema="INFORMATION_SCHEMA",
  160. )
  161. computed_columns = Table(
  162. "computed_columns",
  163. ischema,
  164. Column("object_id", Integer),
  165. Column("name", CoerceUnicode),
  166. Column("is_computed", Boolean),
  167. Column("is_persisted", Boolean),
  168. Column("definition", CoerceUnicode),
  169. schema="sys",
  170. )
  171. sequences = Table(
  172. "SEQUENCES",
  173. ischema,
  174. Column("SEQUENCE_CATALOG", CoerceUnicode, key="sequence_catalog"),
  175. Column("SEQUENCE_SCHEMA", CoerceUnicode, key="sequence_schema"),
  176. Column("SEQUENCE_NAME", CoerceUnicode, key="sequence_name"),
  177. schema="INFORMATION_SCHEMA",
  178. )
  179. class IdentitySqlVariant(TypeDecorator):
  180. r"""This type casts sql_variant columns in the identity_columns view
  181. to numeric. This is required because:
  182. * pyodbc does not support sql_variant
  183. * pymssql under python 2 return the byte representation of the number,
  184. int 1 is returned as "\x01\x00\x00\x00". On python 3 it returns the
  185. correct value as string.
  186. """
  187. impl = Unicode
  188. cache_ok = True
  189. def column_expression(self, colexpr):
  190. return cast(colexpr, Numeric)
  191. identity_columns = Table(
  192. "identity_columns",
  193. ischema,
  194. Column("object_id", Integer),
  195. Column("name", CoerceUnicode),
  196. Column("is_identity", Boolean),
  197. Column("seed_value", IdentitySqlVariant),
  198. Column("increment_value", IdentitySqlVariant),
  199. Column("last_value", IdentitySqlVariant),
  200. Column("is_not_for_replication", Boolean),
  201. schema="sys",
  202. )