Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/sql/schema.py: 55%

1296 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

1# sql/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 

8"""The schema module provides the building blocks for database metadata. 

9 

10Each element within this module describes a database entity which can be 

11created and dropped, or is otherwise part of such an entity. Examples include 

12tables, columns, sequences, and indexes. 

13 

14All entities are subclasses of :class:`~sqlalchemy.schema.SchemaItem`, and as 

15defined in this module they are intended to be agnostic of any vendor-specific 

16constructs. 

17 

18A collection of entities are grouped into a unit called 

19:class:`~sqlalchemy.schema.MetaData`. MetaData serves as a logical grouping of 

20schema elements, and can also be associated with an actual database connection 

21such that operations involving the contained elements can contact the database 

22as needed. 

23 

24Two of the elements here also build upon their "syntactic" counterparts, which 

25are defined in :class:`~sqlalchemy.sql.expression.`, specifically 

26:class:`~sqlalchemy.schema.Table` and :class:`~sqlalchemy.schema.Column`. 

27Since these objects are part of the SQL expression language, they are usable 

28as components in SQL expressions. 

29 

30""" 

31from __future__ import absolute_import 

32 

33import collections 

34 

35import sqlalchemy 

36from . import coercions 

37from . import ddl 

38from . import roles 

39from . import type_api 

40from . import visitors 

41from .base import _bind_or_error 

42from .base import DedupeColumnCollection 

43from .base import DialectKWArgs 

44from .base import Executable 

45from .base import SchemaEventTarget 

46from .coercions import _document_text_coercion 

47from .elements import ClauseElement 

48from .elements import ColumnClause 

49from .elements import ColumnElement 

50from .elements import quoted_name 

51from .elements import TextClause 

52from .selectable import TableClause 

53from .type_api import to_instance 

54from .visitors import InternalTraversal 

55from .. import event 

56from .. import exc 

57from .. import inspection 

58from .. import util 

59 

60 

61RETAIN_SCHEMA = util.symbol( 

62 "retain_schema" 

63 """Symbol indicating that a :class:`_schema.Table`, :class:`.Sequence` 

64 or in some cases a :class:`_schema.ForeignKey` object, in situations 

65 where the object is being copied for a :meth:`.Table.to_metadata` 

66 operation, should retain the schema name that it already has. 

67 

68 """ 

69) 

70 

71BLANK_SCHEMA = util.symbol( 

72 "blank_schema", 

73 """Symbol indicating that a :class:`_schema.Table`, :class:`.Sequence` 

74 or in some cases a :class:`_schema.ForeignKey` object 

75 should have 'None' for its schema, even if the parent 

76 :class:`_schema.MetaData` has specified a schema. 

77 

78 .. versionadded:: 1.0.14 

79 

80 """, 

81) 

82 

83NULL_UNSPECIFIED = util.symbol( 

84 "NULL_UNSPECIFIED", 

85 """Symbol indicating the "nullable" keyword was not passed to a Column. 

86 

87 Normally we would expect None to be acceptable for this but some backends 

88 such as that of SQL Server place special signficance on a "nullability" 

89 value of None. 

90 

91 """, 

92) 

93 

94 

95def _get_table_key(name, schema): 

96 if schema is None: 

97 return name 

98 else: 

99 return schema + "." + name 

100 

101 

102# this should really be in sql/util.py but we'd have to 

103# break an import cycle 

104def _copy_expression(expression, source_table, target_table): 

105 if source_table is None or target_table is None: 

106 return expression 

107 

108 def replace(col): 

109 if ( 

110 isinstance(col, Column) 

111 and col.table is source_table 

112 and col.key in source_table.c 

113 ): 

114 return target_table.c[col.key] 

115 else: 

116 return None 

117 

118 return visitors.replacement_traverse(expression, {}, replace) 

119 

120 

121@inspection._self_inspects 

122class SchemaItem(SchemaEventTarget, visitors.Visitable): 

123 """Base class for items that define a database schema.""" 

124 

125 __visit_name__ = "schema_item" 

126 

127 create_drop_stringify_dialect = "default" 

128 

129 def _init_items(self, *args, **kw): 

130 """Initialize the list of child items for this SchemaItem.""" 

131 for item in args: 

132 if item is not None: 

133 try: 

134 spwd = item._set_parent_with_dispatch 

135 except AttributeError as err: 

136 util.raise_( 

137 exc.ArgumentError( 

138 "'SchemaItem' object, such as a 'Column' or a " 

139 "'Constraint' expected, got %r" % item 

140 ), 

141 replace_context=err, 

142 ) 

143 else: 

144 spwd(self, **kw) 

145 

146 def __repr__(self): 

147 return util.generic_repr(self, omit_kwarg=["info"]) 

148 

149 @util.memoized_property 

150 def info(self): 

151 """Info dictionary associated with the object, allowing user-defined 

152 data to be associated with this :class:`.SchemaItem`. 

153 

154 The dictionary is automatically generated when first accessed. 

155 It can also be specified in the constructor of some objects, 

156 such as :class:`_schema.Table` and :class:`_schema.Column`. 

157 

158 """ 

159 return {} 

160 

161 def _schema_item_copy(self, schema_item): 

162 if "info" in self.__dict__: 

163 schema_item.info = self.info.copy() 

164 schema_item.dispatch._update(self.dispatch) 

165 return schema_item 

166 

167 _use_schema_map = True 

168 

169 

170class Table(DialectKWArgs, SchemaItem, TableClause): 

171 r"""Represent a table in a database. 

172 

173 e.g.:: 

174 

175 mytable = Table( 

176 "mytable", metadata, 

177 Column('mytable_id', Integer, primary_key=True), 

178 Column('value', String(50)) 

179 ) 

180 

181 The :class:`_schema.Table` 

182 object constructs a unique instance of itself based 

183 on its name and optional schema name within the given 

184 :class:`_schema.MetaData` object. Calling the :class:`_schema.Table` 

185 constructor with the same name and same :class:`_schema.MetaData` argument 

186 a second time will return the *same* :class:`_schema.Table` 

187 object - in this way 

188 the :class:`_schema.Table` constructor acts as a registry function. 

189 

190 .. seealso:: 

191 

192 :ref:`metadata_describing` - Introduction to database metadata 

193 

194 Constructor arguments are as follows: 

195 

196 :param name: The name of this table as represented in the database. 

197 

198 The table name, along with the value of the ``schema`` parameter, 

199 forms a key which uniquely identifies this :class:`_schema.Table` 

200 within 

201 the owning :class:`_schema.MetaData` collection. 

202 Additional calls to :class:`_schema.Table` with the same name, 

203 metadata, 

204 and schema name will return the same :class:`_schema.Table` object. 

205 

206 Names which contain no upper case characters 

207 will be treated as case insensitive names, and will not be quoted 

208 unless they are a reserved word or contain special characters. 

209 A name with any number of upper case characters is considered 

210 to be case sensitive, and will be sent as quoted. 

211 

212 To enable unconditional quoting for the table name, specify the flag 

213 ``quote=True`` to the constructor, or use the :class:`.quoted_name` 

214 construct to specify the name. 

215 

216 :param metadata: a :class:`_schema.MetaData` 

217 object which will contain this 

218 table. The metadata is used as a point of association of this table 

219 with other tables which are referenced via foreign key. It also 

220 may be used to associate this table with a particular 

221 :class:`.Connectable`. 

222 

223 :param \*args: Additional positional arguments are used primarily 

224 to add the list of :class:`_schema.Column` 

225 objects contained within this 

226 table. Similar to the style of a CREATE TABLE statement, other 

227 :class:`.SchemaItem` constructs may be added here, including 

228 :class:`.PrimaryKeyConstraint`, and 

229 :class:`_schema.ForeignKeyConstraint`. 

230 

231 :param autoload: Defaults to ``False``, unless 

232 :paramref:`_schema.Table.autoload_with` 

233 is set in which case it defaults to ``True``; 

234 :class:`_schema.Column` objects 

235 for this table should be reflected from the database, possibly 

236 augmenting objects that were explicitly specified. 

237 :class:`_schema.Column` and other objects explicitly set on the 

238 table will replace corresponding reflected objects. 

239 

240 .. deprecated:: 1.4 

241 

242 The autoload parameter is deprecated and will be removed in 

243 version 2.0. Please use the 

244 :paramref:`_schema.Table.autoload_with` parameter, passing an 

245 engine or connection. 

246 

247 .. seealso:: 

248 

249 :ref:`metadata_reflection_toplevel` 

250 

251 :param autoload_replace: Defaults to ``True``; when using 

252 :paramref:`_schema.Table.autoload` 

253 in conjunction with :paramref:`_schema.Table.extend_existing`, 

254 indicates 

255 that :class:`_schema.Column` objects present in the already-existing 

256 :class:`_schema.Table` 

257 object should be replaced with columns of the same 

258 name retrieved from the autoload process. When ``False``, columns 

259 already present under existing names will be omitted from the 

260 reflection process. 

261 

262 Note that this setting does not impact :class:`_schema.Column` objects 

263 specified programmatically within the call to :class:`_schema.Table` 

264 that 

265 also is autoloading; those :class:`_schema.Column` objects will always 

266 replace existing columns of the same name when 

267 :paramref:`_schema.Table.extend_existing` is ``True``. 

268 

269 .. seealso:: 

270 

271 :paramref:`_schema.Table.autoload` 

272 

273 :paramref:`_schema.Table.extend_existing` 

274 

275 :param autoload_with: An :class:`_engine.Engine` or 

276 :class:`_engine.Connection` object, 

277 or a :class:`_reflection.Inspector` object as returned by 

278 :func:`_sa.inspect` 

279 against one, with which this :class:`_schema.Table` 

280 object will be reflected. 

281 When set to a non-None value, the autoload process will take place 

282 for this table against the given engine or connection. 

283 

284 :param extend_existing: When ``True``, indicates that if this 

285 :class:`_schema.Table` is already present in the given 

286 :class:`_schema.MetaData`, 

287 apply further arguments within the constructor to the existing 

288 :class:`_schema.Table`. 

289 

290 If :paramref:`_schema.Table.extend_existing` or 

291 :paramref:`_schema.Table.keep_existing` are not set, 

292 and the given name 

293 of the new :class:`_schema.Table` refers to a :class:`_schema.Table` 

294 that is 

295 already present in the target :class:`_schema.MetaData` collection, 

296 and 

297 this :class:`_schema.Table` 

298 specifies additional columns or other constructs 

299 or flags that modify the table's state, an 

300 error is raised. The purpose of these two mutually-exclusive flags 

301 is to specify what action should be taken when a 

302 :class:`_schema.Table` 

303 is specified that matches an existing :class:`_schema.Table`, 

304 yet specifies 

305 additional constructs. 

306 

307 :paramref:`_schema.Table.extend_existing` 

308 will also work in conjunction 

309 with :paramref:`_schema.Table.autoload` to run a new reflection 

310 operation against the database, even if a :class:`_schema.Table` 

311 of the same name is already present in the target 

312 :class:`_schema.MetaData`; newly reflected :class:`_schema.Column` 

313 objects 

314 and other options will be added into the state of the 

315 :class:`_schema.Table`, potentially overwriting existing columns 

316 and options of the same name. 

317 

318 As is always the case with :paramref:`_schema.Table.autoload`, 

319 :class:`_schema.Column` objects can be specified in the same 

320 :class:`_schema.Table` 

321 constructor, which will take precedence. Below, the existing 

322 table ``mytable`` will be augmented with :class:`_schema.Column` 

323 objects 

324 both reflected from the database, as well as the given 

325 :class:`_schema.Column` 

326 named "y":: 

327 

328 Table("mytable", metadata, 

329 Column('y', Integer), 

330 extend_existing=True, 

331 autoload_with=engine 

332 ) 

333 

334 .. seealso:: 

335 

336 :paramref:`_schema.Table.autoload` 

337 

338 :paramref:`_schema.Table.autoload_replace` 

339 

340 :paramref:`_schema.Table.keep_existing` 

341 

342 

343 :param implicit_returning: True by default - indicates that 

344 RETURNING can be used by default to fetch newly inserted primary key 

345 values, for backends which support this. Note that 

346 :func:`_sa.create_engine` also provides an ``implicit_returning`` 

347 flag. 

348 

349 :param include_columns: A list of strings indicating a subset of 

350 columns to be loaded via the ``autoload`` operation; table columns who 

351 aren't present in this list will not be represented on the resulting 

352 ``Table`` object. Defaults to ``None`` which indicates all columns 

353 should be reflected. 

354 

355 :param resolve_fks: Whether or not to reflect :class:`_schema.Table` 

356 objects 

357 related to this one via :class:`_schema.ForeignKey` objects, when 

358 :paramref:`_schema.Table.autoload` or 

359 :paramref:`_schema.Table.autoload_with` is 

360 specified. Defaults to True. Set to False to disable reflection of 

361 related tables as :class:`_schema.ForeignKey` 

362 objects are encountered; may be 

363 used either to save on SQL calls or to avoid issues with related tables 

364 that can't be accessed. Note that if a related table is already present 

365 in the :class:`_schema.MetaData` collection, or becomes present later, 

366 a 

367 :class:`_schema.ForeignKey` object associated with this 

368 :class:`_schema.Table` will 

369 resolve to that table normally. 

370 

371 .. versionadded:: 1.3 

372 

373 .. seealso:: 

374 

375 :paramref:`.MetaData.reflect.resolve_fks` 

376 

377 

378 :param info: Optional data dictionary which will be populated into the 

379 :attr:`.SchemaItem.info` attribute of this object. 

380 

381 :param keep_existing: When ``True``, indicates that if this Table 

382 is already present in the given :class:`_schema.MetaData`, ignore 

383 further arguments within the constructor to the existing 

384 :class:`_schema.Table`, and return the :class:`_schema.Table` 

385 object as 

386 originally created. This is to allow a function that wishes 

387 to define a new :class:`_schema.Table` on first call, but on 

388 subsequent calls will return the same :class:`_schema.Table`, 

389 without any of the declarations (particularly constraints) 

390 being applied a second time. 

391 

392 If :paramref:`_schema.Table.extend_existing` or 

393 :paramref:`_schema.Table.keep_existing` are not set, 

394 and the given name 

395 of the new :class:`_schema.Table` refers to a :class:`_schema.Table` 

396 that is 

397 already present in the target :class:`_schema.MetaData` collection, 

398 and 

399 this :class:`_schema.Table` 

400 specifies additional columns or other constructs 

401 or flags that modify the table's state, an 

402 error is raised. The purpose of these two mutually-exclusive flags 

403 is to specify what action should be taken when a 

404 :class:`_schema.Table` 

405 is specified that matches an existing :class:`_schema.Table`, 

406 yet specifies 

407 additional constructs. 

408 

409 .. seealso:: 

410 

411 :paramref:`_schema.Table.extend_existing` 

412 

413 :param listeners: A list of tuples of the form ``(<eventname>, <fn>)`` 

414 which will be passed to :func:`.event.listen` upon construction. 

415 This alternate hook to :func:`.event.listen` allows the establishment 

416 of a listener function specific to this :class:`_schema.Table` before 

417 the "autoload" process begins. Historically this has been intended 

418 for use with the :meth:`.DDLEvents.column_reflect` event, however 

419 note that this event hook may now be associated with the 

420 :class:`_schema.MetaData` object directly:: 

421 

422 def listen_for_reflect(table, column_info): 

423 "handle the column reflection event" 

424 # ... 

425 

426 t = Table( 

427 'sometable', 

428 autoload_with=engine, 

429 listeners=[ 

430 ('column_reflect', listen_for_reflect) 

431 ]) 

432 

433 .. seealso:: 

434 

435 :meth:`_events.DDLEvents.column_reflect` 

436 

437 :param must_exist: When ``True``, indicates that this Table must already 

438 be present in the given :class:`_schema.MetaData` collection, else 

439 an exception is raised. 

440 

441 :param prefixes: 

442 A list of strings to insert after CREATE in the CREATE TABLE 

443 statement. They will be separated by spaces. 

444 

445 :param quote: Force quoting of this table's name on or off, corresponding 

446 to ``True`` or ``False``. When left at its default of ``None``, 

447 the column identifier will be quoted according to whether the name is 

448 case sensitive (identifiers with at least one upper case character are 

449 treated as case sensitive), or if it's a reserved word. This flag 

450 is only needed to force quoting of a reserved word which is not known 

451 by the SQLAlchemy dialect. 

452 

453 .. note:: setting this flag to ``False`` will not provide 

454 case-insensitive behavior for table reflection; table reflection 

455 will always search for a mixed-case name in a case sensitive 

456 fashion. Case insensitive names are specified in SQLAlchemy only 

457 by stating the name with all lower case characters. 

458 

459 :param quote_schema: same as 'quote' but applies to the schema identifier. 

460 

461 :param schema: The schema name for this table, which is required if 

462 the table resides in a schema other than the default selected schema 

463 for the engine's database connection. Defaults to ``None``. 

464 

465 If the owning :class:`_schema.MetaData` of this :class:`_schema.Table` 

466 specifies its 

467 own :paramref:`_schema.MetaData.schema` parameter, 

468 then that schema name will 

469 be applied to this :class:`_schema.Table` 

470 if the schema parameter here is set 

471 to ``None``. To set a blank schema name on a :class:`_schema.Table` 

472 that 

473 would otherwise use the schema set on the owning 

474 :class:`_schema.MetaData`, 

475 specify the special symbol :attr:`.BLANK_SCHEMA`. 

476 

477 .. versionadded:: 1.0.14 Added the :attr:`.BLANK_SCHEMA` symbol to 

478 allow a :class:`_schema.Table` 

479 to have a blank schema name even when the 

480 parent :class:`_schema.MetaData` specifies 

481 :paramref:`_schema.MetaData.schema`. 

482 

483 The quoting rules for the schema name are the same as those for the 

484 ``name`` parameter, in that quoting is applied for reserved words or 

485 case-sensitive names; to enable unconditional quoting for the schema 

486 name, specify the flag ``quote_schema=True`` to the constructor, or use 

487 the :class:`.quoted_name` construct to specify the name. 

488 

489 :param comment: Optional string that will render an SQL comment on table 

490 creation. 

491 

492 .. versionadded:: 1.2 Added the :paramref:`_schema.Table.comment` 

493 parameter 

494 to :class:`_schema.Table`. 

495 

496 :param \**kw: Additional keyword arguments not mentioned above are 

497 dialect specific, and passed in the form ``<dialectname>_<argname>``. 

498 See the documentation regarding an individual dialect at 

499 :ref:`dialect_toplevel` for detail on documented arguments. 

500 

501 """ 

502 

503 __visit_name__ = "table" 

504 

505 constraints = None 

506 """A collection of all :class:`_schema.Constraint` objects associated with 

507 this :class:`_schema.Table`. 

508 

509 Includes :class:`_schema.PrimaryKeyConstraint`, 

510 :class:`_schema.ForeignKeyConstraint`, :class:`_schema.UniqueConstraint`, 

511 :class:`_schema.CheckConstraint`. A separate collection 

512 :attr:`_schema.Table.foreign_key_constraints` refers to the collection 

513 of all :class:`_schema.ForeignKeyConstraint` objects, and the 

514 :attr:`_schema.Table.primary_key` attribute refers to the single 

515 :class:`_schema.PrimaryKeyConstraint` associated with the 

516 :class:`_schema.Table`. 

517 

518 .. seealso:: 

519 

520 :attr:`_schema.Table.constraints` 

521 

522 :attr:`_schema.Table.primary_key` 

523 

524 :attr:`_schema.Table.foreign_key_constraints` 

525 

526 :attr:`_schema.Table.indexes` 

527 

528 :class:`_reflection.Inspector` 

529 

530 

531 """ 

532 

533 indexes = None 

534 """A collection of all :class:`_schema.Index` objects associated with this 

535 :class:`_schema.Table`. 

536 

537 .. seealso:: 

538 

539 :meth:`_reflection.Inspector.get_indexes` 

540 

541 """ 

542 

543 _traverse_internals = TableClause._traverse_internals + [ 

544 ("schema", InternalTraversal.dp_string) 

545 ] 

546 

547 _is_table = True 

548 

549 def _gen_cache_key(self, anon_map, bindparams): 

550 if self._annotations: 

551 return (self,) + self._annotations_cache_key 

552 else: 

553 return (self,) 

554 

555 @util.deprecated_params( 

556 mustexist=( 

557 "1.4", 

558 "Deprecated alias of :paramref:`_schema.Table.must_exist`", 

559 ), 

560 autoload=( 

561 "2.0", 

562 "The autoload parameter is deprecated and will be removed in " 

563 "version 2.0. Please use the " 

564 "autoload_with parameter, passing an engine or connection.", 

565 ), 

566 ) 

567 def __new__(cls, *args, **kw): 

568 if not args and not kw: 

569 # python3k pickle seems to call this 

570 return object.__new__(cls) 

571 

572 try: 

573 name, metadata, args = args[0], args[1], args[2:] 

574 except IndexError: 

575 raise TypeError( 

576 "Table() takes at least two positional-only " 

577 "arguments 'name' and 'metadata'" 

578 ) 

579 

580 schema = kw.get("schema", None) 

581 if schema is None: 

582 schema = metadata.schema 

583 elif schema is BLANK_SCHEMA: 

584 schema = None 

585 keep_existing = kw.get("keep_existing", False) 

586 extend_existing = kw.get("extend_existing", False) 

587 

588 if keep_existing and extend_existing: 

589 msg = "keep_existing and extend_existing are mutually exclusive." 

590 raise exc.ArgumentError(msg) 

591 

592 must_exist = kw.pop("must_exist", kw.pop("mustexist", False)) 

593 key = _get_table_key(name, schema) 

594 if key in metadata.tables: 

595 if not keep_existing and not extend_existing and bool(args): 

596 raise exc.InvalidRequestError( 

597 "Table '%s' is already defined for this MetaData " 

598 "instance. Specify 'extend_existing=True' " 

599 "to redefine " 

600 "options and columns on an " 

601 "existing Table object." % key 

602 ) 

603 table = metadata.tables[key] 

604 if extend_existing: 

605 table._init_existing(*args, **kw) 

606 return table 

607 else: 

608 if must_exist: 

609 raise exc.InvalidRequestError("Table '%s' not defined" % (key)) 

610 table = object.__new__(cls) 

611 table.dispatch.before_parent_attach(table, metadata) 

612 metadata._add_table(name, schema, table) 

613 try: 

614 table._init(name, metadata, *args, **kw) 

615 table.dispatch.after_parent_attach(table, metadata) 

616 return table 

617 except Exception: 

618 with util.safe_reraise(): 

619 metadata._remove_table(name, schema) 

620 

621 def __init__(self, *args, **kw): 

622 """Constructor for :class:`_schema.Table`. 

623 

624 This method is a no-op. See the top-level 

625 documentation for :class:`_schema.Table` 

626 for constructor arguments. 

627 

628 """ 

629 # __init__ is overridden to prevent __new__ from 

630 # calling the superclass constructor. 

631 

632 def _init(self, name, metadata, *args, **kwargs): 

633 super(Table, self).__init__( 

634 quoted_name(name, kwargs.pop("quote", None)) 

635 ) 

636 self.metadata = metadata 

637 

638 self.schema = kwargs.pop("schema", None) 

639 if self.schema is None: 

640 self.schema = metadata.schema 

641 elif self.schema is BLANK_SCHEMA: 

642 self.schema = None 

643 else: 

644 quote_schema = kwargs.pop("quote_schema", None) 

645 self.schema = quoted_name(self.schema, quote_schema) 

646 

647 self.indexes = set() 

648 self.constraints = set() 

649 PrimaryKeyConstraint( 

650 _implicit_generated=True 

651 )._set_parent_with_dispatch(self) 

652 self.foreign_keys = set() 

653 self._extra_dependencies = set() 

654 if self.schema is not None: 

655 self.fullname = "%s.%s" % (self.schema, self.name) 

656 else: 

657 self.fullname = self.name 

658 

659 autoload_with = kwargs.pop("autoload_with", None) 

660 autoload = kwargs.pop("autoload", autoload_with is not None) 

661 # this argument is only used with _init_existing() 

662 kwargs.pop("autoload_replace", True) 

663 keep_existing = kwargs.pop("keep_existing", False) 

664 extend_existing = kwargs.pop("extend_existing", False) 

665 _extend_on = kwargs.pop("_extend_on", None) 

666 

667 resolve_fks = kwargs.pop("resolve_fks", True) 

668 include_columns = kwargs.pop("include_columns", None) 

669 

670 self.implicit_returning = kwargs.pop("implicit_returning", True) 

671 

672 self.comment = kwargs.pop("comment", None) 

673 

674 if "info" in kwargs: 

675 self.info = kwargs.pop("info") 

676 if "listeners" in kwargs: 

677 listeners = kwargs.pop("listeners") 

678 for evt, fn in listeners: 

679 event.listen(self, evt, fn) 

680 

681 self._prefixes = kwargs.pop("prefixes", None) or [] 

682 

683 self._extra_kwargs(**kwargs) 

684 

685 # load column definitions from the database if 'autoload' is defined 

686 # we do it after the table is in the singleton dictionary to support 

687 # circular foreign keys 

688 if autoload: 

689 self._autoload( 

690 metadata, 

691 autoload_with, 

692 include_columns, 

693 _extend_on=_extend_on, 

694 resolve_fks=resolve_fks, 

695 ) 

696 

697 # initialize all the column, etc. objects. done after reflection to 

698 # allow user-overrides 

699 

700 self._init_items( 

701 *args, 

702 allow_replacements=extend_existing or keep_existing or autoload 

703 ) 

704 

705 def _autoload( 

706 self, 

707 metadata, 

708 autoload_with, 

709 include_columns, 

710 exclude_columns=(), 

711 resolve_fks=True, 

712 _extend_on=None, 

713 ): 

714 if autoload_with is None: 

715 autoload_with = _bind_or_error( 

716 metadata, 

717 msg="No engine is bound to this Table's MetaData. " 

718 "Pass an engine to the Table via " 

719 "autoload_with=<someengine_or_connection>", 

720 ) 

721 

722 insp = inspection.inspect(autoload_with) 

723 with insp._inspection_context() as conn_insp: 

724 conn_insp.reflect_table( 

725 self, 

726 include_columns, 

727 exclude_columns, 

728 resolve_fks, 

729 _extend_on=_extend_on, 

730 ) 

731 

732 @property 

733 def _sorted_constraints(self): 

734 """Return the set of constraints as a list, sorted by creation 

735 order. 

736 

737 """ 

738 return sorted(self.constraints, key=lambda c: c._creation_order) 

739 

740 @property 

741 def foreign_key_constraints(self): 

742 """:class:`_schema.ForeignKeyConstraint` objects referred to by this 

743 :class:`_schema.Table`. 

744 

745 This list is produced from the collection of 

746 :class:`_schema.ForeignKey` 

747 objects currently associated. 

748 

749 

750 .. seealso:: 

751 

752 :attr:`_schema.Table.constraints` 

753 

754 :attr:`_schema.Table.foreign_keys` 

755 

756 :attr:`_schema.Table.indexes` 

757 

758 """ 

759 return set(fkc.constraint for fkc in self.foreign_keys) 

760 

761 def _init_existing(self, *args, **kwargs): 

762 autoload_with = kwargs.pop("autoload_with", None) 

763 autoload = kwargs.pop("autoload", autoload_with is not None) 

764 autoload_replace = kwargs.pop("autoload_replace", True) 

765 schema = kwargs.pop("schema", None) 

766 _extend_on = kwargs.pop("_extend_on", None) 

767 # these arguments are only used with _init() 

768 kwargs.pop("extend_existing", False) 

769 kwargs.pop("keep_existing", False) 

770 

771 if schema and schema != self.schema: 

772 raise exc.ArgumentError( 

773 "Can't change schema of existing table from '%s' to '%s'", 

774 (self.schema, schema), 

775 ) 

776 

777 include_columns = kwargs.pop("include_columns", None) 

778 if include_columns is not None: 

779 for c in self.c: 

780 if c.name not in include_columns: 

781 self._columns.remove(c) 

782 

783 resolve_fks = kwargs.pop("resolve_fks", True) 

784 

785 for key in ("quote", "quote_schema"): 

786 if key in kwargs: 

787 raise exc.ArgumentError( 

788 "Can't redefine 'quote' or 'quote_schema' arguments" 

789 ) 

790 

791 # update `self` with these kwargs, if provided 

792 self.comment = kwargs.pop("comment", self.comment) 

793 self.implicit_returning = kwargs.pop( 

794 "implicit_returning", self.implicit_returning 

795 ) 

796 self.info = kwargs.pop("info", self.info) 

797 

798 if autoload: 

799 if not autoload_replace: 

800 # don't replace columns already present. 

801 # we'd like to do this for constraints also however we don't 

802 # have simple de-duping for unnamed constraints. 

803 exclude_columns = [c.name for c in self.c] 

804 else: 

805 exclude_columns = () 

806 self._autoload( 

807 self.metadata, 

808 autoload_with, 

809 include_columns, 

810 exclude_columns, 

811 resolve_fks, 

812 _extend_on=_extend_on, 

813 ) 

814 

815 self._extra_kwargs(**kwargs) 

816 self._init_items(*args) 

817 

818 def _extra_kwargs(self, **kwargs): 

819 self._validate_dialect_kwargs(kwargs) 

820 

821 def _init_collections(self): 

822 pass 

823 

824 def _reset_exported(self): 

825 pass 

826 

827 @property 

828 def _autoincrement_column(self): 

829 return self.primary_key._autoincrement_column 

830 

831 @property 

832 def key(self): 

833 """Return the 'key' for this :class:`_schema.Table`. 

834 

835 This value is used as the dictionary key within the 

836 :attr:`_schema.MetaData.tables` collection. It is typically the same 

837 as that of :attr:`_schema.Table.name` for a table with no 

838 :attr:`_schema.Table.schema` 

839 set; otherwise it is typically of the form 

840 ``schemaname.tablename``. 

841 

842 """ 

843 return _get_table_key(self.name, self.schema) 

844 

845 def __repr__(self): 

846 return "Table(%s)" % ", ".join( 

847 [repr(self.name)] 

848 + [repr(self.metadata)] 

849 + [repr(x) for x in self.columns] 

850 + ["%s=%s" % (k, repr(getattr(self, k))) for k in ["schema"]] 

851 ) 

852 

853 def __str__(self): 

854 return _get_table_key(self.description, self.schema) 

855 

856 @property 

857 def bind(self): 

858 """Return the connectable associated with this Table.""" 

859 

860 return self.metadata and self.metadata.bind or None 

861 

862 def add_is_dependent_on(self, table): 

863 """Add a 'dependency' for this Table. 

864 

865 This is another Table object which must be created 

866 first before this one can, or dropped after this one. 

867 

868 Usually, dependencies between tables are determined via 

869 ForeignKey objects. However, for other situations that 

870 create dependencies outside of foreign keys (rules, inheriting), 

871 this method can manually establish such a link. 

872 

873 """ 

874 self._extra_dependencies.add(table) 

875 

876 def append_column(self, column, replace_existing=False): 

877 """Append a :class:`_schema.Column` to this :class:`_schema.Table`. 

878 

879 The "key" of the newly added :class:`_schema.Column`, i.e. the 

880 value of its ``.key`` attribute, will then be available 

881 in the ``.c`` collection of this :class:`_schema.Table`, and the 

882 column definition will be included in any CREATE TABLE, SELECT, 

883 UPDATE, etc. statements generated from this :class:`_schema.Table` 

884 construct. 

885 

886 Note that this does **not** change the definition of the table 

887 as it exists within any underlying database, assuming that 

888 table has already been created in the database. Relational 

889 databases support the addition of columns to existing tables 

890 using the SQL ALTER command, which would need to be 

891 emitted for an already-existing table that doesn't contain 

892 the newly added column. 

893 

894 :param replace_existing: When ``True``, allows replacing existing 

895 columns. When ``False``, the default, an warning will be raised 

896 if a column with the same ``.key`` already exists. A future 

897 version of sqlalchemy will instead rise a warning. 

898 

899 .. versionadded:: 1.4.0 

900 """ 

901 

902 column._set_parent_with_dispatch( 

903 self, allow_replacements=replace_existing 

904 ) 

905 

906 def append_constraint(self, constraint): 

907 """Append a :class:`_schema.Constraint` to this 

908 :class:`_schema.Table`. 

909 

910 This has the effect of the constraint being included in any 

911 future CREATE TABLE statement, assuming specific DDL creation 

912 events have not been associated with the given 

913 :class:`_schema.Constraint` object. 

914 

915 Note that this does **not** produce the constraint within the 

916 relational database automatically, for a table that already exists 

917 in the database. To add a constraint to an 

918 existing relational database table, the SQL ALTER command must 

919 be used. SQLAlchemy also provides the 

920 :class:`.AddConstraint` construct which can produce this SQL when 

921 invoked as an executable clause. 

922 

923 """ 

924 

925 constraint._set_parent_with_dispatch(self) 

926 

927 def _set_parent(self, metadata, **kw): 

928 metadata._add_table(self.name, self.schema, self) 

929 self.metadata = metadata 

930 

931 @util.deprecated( 

932 "1.4", 

933 "The :meth:`_schema.Table.exists` method is deprecated and will be " 

934 "removed in a future release. Please refer to " 

935 ":meth:`_reflection.Inspector.has_table`.", 

936 ) 

937 def exists(self, bind=None): 

938 """Return True if this table exists.""" 

939 

940 if bind is None: 

941 bind = _bind_or_error(self) 

942 

943 insp = inspection.inspect(bind) 

944 return insp.has_table(self.name, schema=self.schema) 

945 

946 def create(self, bind=None, checkfirst=False): 

947 """Issue a ``CREATE`` statement for this 

948 :class:`_schema.Table`, using the given :class:`.Connectable` 

949 for connectivity. 

950 

951 .. note:: the "bind" argument will be required in 

952 SQLAlchemy 2.0. 

953 

954 .. seealso:: 

955 

956 :meth:`_schema.MetaData.create_all`. 

957 

958 """ 

959 

960 if bind is None: 

961 bind = _bind_or_error(self) 

962 bind._run_ddl_visitor(ddl.SchemaGenerator, self, checkfirst=checkfirst) 

963 

964 def drop(self, bind=None, checkfirst=False): 

965 """Issue a ``DROP`` statement for this 

966 :class:`_schema.Table`, using the given :class:`.Connectable` 

967 for connectivity. 

968 

969 .. note:: the "bind" argument will be required in 

970 SQLAlchemy 2.0. 

971 

972 .. seealso:: 

973 

974 :meth:`_schema.MetaData.drop_all`. 

975 

976 """ 

977 if bind is None: 

978 bind = _bind_or_error(self) 

979 bind._run_ddl_visitor(ddl.SchemaDropper, self, checkfirst=checkfirst) 

980 

981 @util.deprecated( 

982 "1.4", 

983 ":meth:`_schema.Table.tometadata` is renamed to " 

984 ":meth:`_schema.Table.to_metadata`", 

985 ) 

986 def tometadata( 

987 self, 

988 metadata, 

989 schema=RETAIN_SCHEMA, 

990 referred_schema_fn=None, 

991 name=None, 

992 ): 

993 """Return a copy of this :class:`_schema.Table` 

994 associated with a different 

995 :class:`_schema.MetaData`. 

996 

997 See :meth:`_schema.Table.to_metadata` for a full description. 

998 

999 """ 

1000 return self.to_metadata( 

1001 metadata, 

1002 schema=schema, 

1003 referred_schema_fn=referred_schema_fn, 

1004 name=name, 

1005 ) 

1006 

1007 def to_metadata( 

1008 self, 

1009 metadata, 

1010 schema=RETAIN_SCHEMA, 

1011 referred_schema_fn=None, 

1012 name=None, 

1013 ): 

1014 """Return a copy of this :class:`_schema.Table` associated with a 

1015 different :class:`_schema.MetaData`. 

1016 

1017 E.g.:: 

1018 

1019 m1 = MetaData() 

1020 

1021 user = Table('user', m1, Column('id', Integer, primary_key=True)) 

1022 

1023 m2 = MetaData() 

1024 user_copy = user.to_metadata(m2) 

1025 

1026 .. versionchanged:: 1.4 The :meth:`_schema.Table.to_metadata` function 

1027 was renamed from :meth:`_schema.Table.tometadata`. 

1028 

1029 

1030 :param metadata: Target :class:`_schema.MetaData` object, 

1031 into which the 

1032 new :class:`_schema.Table` object will be created. 

1033 

1034 :param schema: optional string name indicating the target schema. 

1035 Defaults to the special symbol :attr:`.RETAIN_SCHEMA` which indicates 

1036 that no change to the schema name should be made in the new 

1037 :class:`_schema.Table`. If set to a string name, the new 

1038 :class:`_schema.Table` 

1039 will have this new name as the ``.schema``. If set to ``None``, the 

1040 schema will be set to that of the schema set on the target 

1041 :class:`_schema.MetaData`, which is typically ``None`` as well, 

1042 unless 

1043 set explicitly:: 

1044 

1045 m2 = MetaData(schema='newschema') 

1046 

1047 # user_copy_one will have "newschema" as the schema name 

1048 user_copy_one = user.to_metadata(m2, schema=None) 

1049 

1050 m3 = MetaData() # schema defaults to None 

1051 

1052 # user_copy_two will have None as the schema name 

1053 user_copy_two = user.to_metadata(m3, schema=None) 

1054 

1055 :param referred_schema_fn: optional callable which can be supplied 

1056 in order to provide for the schema name that should be assigned 

1057 to the referenced table of a :class:`_schema.ForeignKeyConstraint`. 

1058 The callable accepts this parent :class:`_schema.Table`, the 

1059 target schema that we are changing to, the 

1060 :class:`_schema.ForeignKeyConstraint` object, and the existing 

1061 "target schema" of that constraint. The function should return the 

1062 string schema name that should be applied. To reset the schema 

1063 to "none", return the symbol :data:`.BLANK_SCHEMA`. To effect no 

1064 change, return ``None`` or :data:`.RETAIN_SCHEMA`. 

1065 

1066 .. versionchanged:: 1.4.33 The ``referred_schema_fn`` function 

1067 may return the :data:`.BLANK_SCHEMA` or :data:`.RETAIN_SCHEMA` 

1068 symbols. 

1069 

1070 E.g.:: 

1071 

1072 def referred_schema_fn(table, to_schema, 

1073 constraint, referred_schema): 

1074 if referred_schema == 'base_tables': 

1075 return referred_schema 

1076 else: 

1077 return to_schema 

1078 

1079 new_table = table.to_metadata(m2, schema="alt_schema", 

1080 referred_schema_fn=referred_schema_fn) 

1081 

1082 .. versionadded:: 0.9.2 

1083 

1084 :param name: optional string name indicating the target table name. 

1085 If not specified or None, the table name is retained. This allows 

1086 a :class:`_schema.Table` to be copied to the same 

1087 :class:`_schema.MetaData` target 

1088 with a new name. 

1089 

1090 .. versionadded:: 1.0.0 

1091 

1092 """ 

1093 if name is None: 

1094 name = self.name 

1095 if schema is RETAIN_SCHEMA: 

1096 schema = self.schema 

1097 elif schema is None: 

1098 schema = metadata.schema 

1099 key = _get_table_key(name, schema) 

1100 if key in metadata.tables: 

1101 util.warn( 

1102 "Table '%s' already exists within the given " 

1103 "MetaData - not copying." % self.description 

1104 ) 

1105 return metadata.tables[key] 

1106 

1107 args = [] 

1108 for c in self.columns: 

1109 args.append(c._copy(schema=schema)) 

1110 table = Table( 

1111 name, 

1112 metadata, 

1113 schema=schema, 

1114 comment=self.comment, 

1115 *args, 

1116 **self.kwargs 

1117 ) 

1118 for c in self.constraints: 

1119 if isinstance(c, ForeignKeyConstraint): 

1120 referred_schema = c._referred_schema 

1121 if referred_schema_fn: 

1122 fk_constraint_schema = referred_schema_fn( 

1123 self, schema, c, referred_schema 

1124 ) 

1125 else: 

1126 fk_constraint_schema = ( 

1127 schema if referred_schema == self.schema else None 

1128 ) 

1129 table.append_constraint( 

1130 c._copy(schema=fk_constraint_schema, target_table=table) 

1131 ) 

1132 elif not c._type_bound: 

1133 # skip unique constraints that would be generated 

1134 # by the 'unique' flag on Column 

1135 if c._column_flag: 

1136 continue 

1137 

1138 table.append_constraint( 

1139 c._copy(schema=schema, target_table=table) 

1140 ) 

1141 for index in self.indexes: 

1142 # skip indexes that would be generated 

1143 # by the 'index' flag on Column 

1144 if index._column_flag: 

1145 continue 

1146 Index( 

1147 index.name, 

1148 unique=index.unique, 

1149 *[ 

1150 _copy_expression(expr, self, table) 

1151 for expr in index.expressions 

1152 ], 

1153 _table=table, 

1154 **index.kwargs 

1155 ) 

1156 return self._schema_item_copy(table) 

1157 

1158 

1159class Column(DialectKWArgs, SchemaItem, ColumnClause): 

1160 """Represents a column in a database table.""" 

1161 

1162 __visit_name__ = "column" 

1163 

1164 inherit_cache = True 

1165 

1166 def __init__(self, *args, **kwargs): 

1167 r""" 

1168 Construct a new ``Column`` object. 

1169 

1170 :param name: The name of this column as represented in the database. 

1171 This argument may be the first positional argument, or specified 

1172 via keyword. 

1173 

1174 Names which contain no upper case characters 

1175 will be treated as case insensitive names, and will not be quoted 

1176 unless they are a reserved word. Names with any number of upper 

1177 case characters will be quoted and sent exactly. Note that this 

1178 behavior applies even for databases which standardize upper 

1179 case names as case insensitive such as Oracle. 

1180 

1181 The name field may be omitted at construction time and applied 

1182 later, at any time before the Column is associated with a 

1183 :class:`_schema.Table`. This is to support convenient 

1184 usage within the :mod:`~sqlalchemy.ext.declarative` extension. 

1185 

1186 :param type\_: The column's type, indicated using an instance which 

1187 subclasses :class:`~sqlalchemy.types.TypeEngine`. If no arguments 

1188 are required for the type, the class of the type can be sent 

1189 as well, e.g.:: 

1190 

1191 # use a type with arguments 

1192 Column('data', String(50)) 

1193 

1194 # use no arguments 

1195 Column('level', Integer) 

1196 

1197 The ``type`` argument may be the second positional argument 

1198 or specified by keyword. 

1199 

1200 If the ``type`` is ``None`` or is omitted, it will first default to 

1201 the special type :class:`.NullType`. If and when this 

1202 :class:`_schema.Column` is made to refer to another column using 

1203 :class:`_schema.ForeignKey` and/or 

1204 :class:`_schema.ForeignKeyConstraint`, the type 

1205 of the remote-referenced column will be copied to this column as 

1206 well, at the moment that the foreign key is resolved against that 

1207 remote :class:`_schema.Column` object. 

1208 

1209 .. versionchanged:: 0.9.0 

1210 Support for propagation of type to a :class:`_schema.Column` 

1211 from its 

1212 :class:`_schema.ForeignKey` object has been improved and should be 

1213 more reliable and timely. 

1214 

1215 :param \*args: Additional positional arguments include various 

1216 :class:`.SchemaItem` derived constructs which will be applied 

1217 as options to the column. These include instances of 

1218 :class:`.Constraint`, :class:`_schema.ForeignKey`, 

1219 :class:`.ColumnDefault`, :class:`.Sequence`, :class:`.Computed` 

1220 :class:`.Identity`. In some cases an 

1221 equivalent keyword argument is available such as ``server_default``, 

1222 ``default`` and ``unique``. 

1223 

1224 :param autoincrement: Set up "auto increment" semantics for an 

1225 **integer primary key column with no foreign key dependencies** 

1226 (see later in this docstring for a more specific definition). 

1227 This may influence the :term:`DDL` that will be emitted for 

1228 this column during a table create, as well as how the column 

1229 will be considered when INSERT statements are compiled and 

1230 executed. 

1231 

1232 The default value is the string ``"auto"``, 

1233 which indicates that a single-column (i.e. non-composite) primary key 

1234 that is of an INTEGER type with no other client-side or server-side 

1235 default constructs indicated should receive auto increment semantics 

1236 automatically. Other values include ``True`` (force this column to 

1237 have auto-increment semantics for a :term:`composite primary key` as 

1238 well), ``False`` (this column should never have auto-increment 

1239 semantics), and the string ``"ignore_fk"`` (special-case for foreign 

1240 key columns, see below). 

1241 

1242 The term "auto increment semantics" refers both to the kind of DDL 

1243 that will be emitted for the column within a CREATE TABLE statement, 

1244 when methods such as :meth:`.MetaData.create_all` and 

1245 :meth:`.Table.create` are invoked, as well as how the column will be 

1246 considered when an INSERT statement is compiled and emitted to the 

1247 database: 

1248 

1249 * **DDL rendering** (i.e. :meth:`.MetaData.create_all`, 

1250 :meth:`.Table.create`): When used on a :class:`.Column` that has 

1251 no other 

1252 default-generating construct associated with it (such as a 

1253 :class:`.Sequence` or :class:`.Identity` construct), the parameter 

1254 will imply that database-specific keywords such as PostgreSQL 

1255 ``SERIAL``, MySQL ``AUTO_INCREMENT``, or ``IDENTITY`` on SQL Server 

1256 should also be rendered. Not every database backend has an 

1257 "implied" default generator available; for example the Oracle 

1258 backend always needs an explicit construct such as 

1259 :class:`.Identity` to be included with a :class:`.Column` in order 

1260 for the DDL rendered to include auto-generating constructs to also 

1261 be produced in the database. 

1262 

1263 * **INSERT semantics** (i.e. when a :func:`_sql.insert` construct is 

1264 compiled into a SQL string and is then executed on a database using 

1265 :meth:`_engine.Connection.execute` or equivalent): A single-row 

1266 INSERT statement will be known to produce a new integer primary key 

1267 value automatically for this column, which will be accessible 

1268 after the statement is invoked via the 

1269 :attr:`.CursorResult.inserted_primary_key` attribute upon the 

1270 :class:`_result.Result` object. This also applies towards use of the 

1271 ORM when ORM-mapped objects are persisted to the database, 

1272 indicating that a new integer primary key will be available to 

1273 become part of the :term:`identity key` for that object. This 

1274 behavior takes place regardless of what DDL constructs are 

1275 associated with the :class:`_schema.Column` and is independent 

1276 of the "DDL Rendering" behavior discussed in the previous note 

1277 above. 

1278 

1279 The parameter may be set to ``True`` to indicate that a column which 

1280 is part of a composite (i.e. multi-column) primary key should 

1281 have autoincrement semantics, though note that only one column 

1282 within a primary key may have this setting. It can also 

1283 be set to ``True`` to indicate autoincrement semantics on a 

1284 column that has a client-side or server-side default configured, 

1285 however note that not all dialects can accommodate all styles 

1286 of default as an "autoincrement". It can also be 

1287 set to ``False`` on a single-column primary key that has a 

1288 datatype of INTEGER in order to disable auto increment semantics 

1289 for that column. 

1290 

1291 .. versionchanged:: 1.1 The autoincrement flag now defaults to 

1292 ``"auto"`` which indicates autoincrement semantics by default 

1293 for single-column integer primary keys only; for composite 

1294 (multi-column) primary keys, autoincrement is never implicitly 

1295 enabled; as always, ``autoincrement=True`` will allow for 

1296 at most one of those columns to be an "autoincrement" column. 

1297 ``autoincrement=True`` may also be set on a 

1298 :class:`_schema.Column` 

1299 that has an explicit client-side or server-side default, 

1300 subject to limitations of the backend database and dialect. 

1301 

1302 The setting *only* has an effect for columns which are: 

1303 

1304 * Integer derived (i.e. INT, SMALLINT, BIGINT). 

1305 

1306 * Part of the primary key 

1307 

1308 * Not referring to another column via :class:`_schema.ForeignKey`, 

1309 unless 

1310 the value is specified as ``'ignore_fk'``:: 

1311 

1312 # turn on autoincrement for this column despite 

1313 # the ForeignKey() 

1314 Column('id', ForeignKey('other.id'), 

1315 primary_key=True, autoincrement='ignore_fk') 

1316 

1317 It is typically not desirable to have "autoincrement" enabled on a 

1318 column that refers to another via foreign key, as such a column is 

1319 required to refer to a value that originates from elsewhere. 

1320 

1321 The setting has these effects on columns that meet the 

1322 above criteria: 

1323 

1324 * DDL issued for the column, if the column does not already include 

1325 a default generating construct supported by the backend such as 

1326 :class:`.Identity`, will include database-specific 

1327 keywords intended to signify this column as an 

1328 "autoincrement" column for specific backends. Behavior for 

1329 primary SQLAlchemy dialects includes: 

1330 

1331 * AUTO INCREMENT on MySQL and MariaDB 

1332 * SERIAL on PostgreSQL 

1333 * IDENTITY on MS-SQL - this occurs even without the 

1334 :class:`.Identity` construct as the 

1335 :paramref:`.Column.autoincrement` parameter pre-dates this 

1336 construct. 

1337 * SQLite - SQLite integer primary key columns are implicitly 

1338 "auto incrementing" and no additional keywords are rendered; 

1339 to render the special SQLite keyword ``AUTOINCREMENT`` 

1340 is not included as this is unnecessary and not recommended 

1341 by the database vendor. See the section 

1342 :ref:`sqlite_autoincrement` for more background. 

1343 * Oracle - The Oracle dialect has no default "autoincrement" 

1344 feature available at this time, instead the :class:`.Identity` 

1345 construct is recommended to achieve this (the :class:`.Sequence` 

1346 construct may also be used). 

1347 * Third-party dialects - consult those dialects' documentation 

1348 for details on their specific behaviors. 

1349 

1350 * When a single-row :func:`_sql.insert` construct is compiled and 

1351 executed, which does not set the :meth:`_sql.Insert.inline` 

1352 modifier, newly generated primary key values for this column 

1353 will be automatically retrieved upon statement execution 

1354 using a method specific to the database driver in use: 

1355 

1356 * MySQL, SQLite - calling upon ``cursor.lastrowid()`` 

1357 (see 

1358 `https://www.python.org/dev/peps/pep-0249/#lastrowid 

1359 <https://www.python.org/dev/peps/pep-0249/#lastrowid>`_) 

1360 * PostgreSQL, SQL Server, Oracle - use RETURNING or an equivalent 

1361 construct when rendering an INSERT statement, and then retrieving 

1362 the newly generated primary key values after execution 

1363 * PostgreSQL, Oracle for :class:`_schema.Table` objects that 

1364 set :paramref:`_schema.Table.implicit_returning` to False - 

1365 for a :class:`.Sequence` only, the :class:`.Sequence` is invoked 

1366 explicitly before the INSERT statement takes place so that the 

1367 newly generated primary key value is available to the client 

1368 * SQL Server for :class:`_schema.Table` objects that 

1369 set :paramref:`_schema.Table.implicit_returning` to False - 

1370 the ``SELECT scope_identity()`` construct is used after the 

1371 INSERT statement is invoked to retrieve the newly generated 

1372 primary key value. 

1373 * Third-party dialects - consult those dialects' documentation 

1374 for details on their specific behaviors. 

1375 

1376 * For multiple-row :func:`_sql.insert` constructs invoked with 

1377 a list of parameters (i.e. "executemany" semantics), primary-key 

1378 retrieving behaviors are generally disabled, however there may 

1379 be special APIs that may be used to retrieve lists of new 

1380 primary key values for an "executemany", such as the psycopg2 

1381 "fast insertmany" feature. Such features are very new and 

1382 may not yet be well covered in documentation. 

1383 

1384 :param default: A scalar, Python callable, or 

1385 :class:`_expression.ColumnElement` expression representing the 

1386 *default value* for this column, which will be invoked upon insert 

1387 if this column is otherwise not specified in the VALUES clause of 

1388 the insert. This is a shortcut to using :class:`.ColumnDefault` as 

1389 a positional argument; see that class for full detail on the 

1390 structure of the argument. 

1391 

1392 Contrast this argument to 

1393 :paramref:`_schema.Column.server_default` 

1394 which creates a default generator on the database side. 

1395 

1396 .. seealso:: 

1397 

1398 :ref:`metadata_defaults_toplevel` 

1399 

1400 :param doc: optional String that can be used by the ORM or similar 

1401 to document attributes on the Python side. This attribute does 

1402 **not** render SQL comments; use the 

1403 :paramref:`_schema.Column.comment` 

1404 parameter for this purpose. 

1405 

1406 :param key: An optional string identifier which will identify this 

1407 ``Column`` object on the :class:`_schema.Table`. 

1408 When a key is provided, 

1409 this is the only identifier referencing the ``Column`` within the 

1410 application, including ORM attribute mapping; the ``name`` field 

1411 is used only when rendering SQL. 

1412 

1413 :param index: When ``True``, indicates that a :class:`_schema.Index` 

1414 construct will be automatically generated for this 

1415 :class:`_schema.Column`, which will result in a "CREATE INDEX" 

1416 statement being emitted for the :class:`_schema.Table` when the DDL 

1417 create operation is invoked. 

1418 

1419 Using this flag is equivalent to making use of the 

1420 :class:`_schema.Index` construct explicitly at the level of the 

1421 :class:`_schema.Table` construct itself:: 

1422 

1423 Table( 

1424 "some_table", 

1425 metadata, 

1426 Column("x", Integer), 

1427 Index("ix_some_table_x", "x") 

1428 ) 

1429 

1430 To add the :paramref:`_schema.Index.unique` flag to the 

1431 :class:`_schema.Index`, set both the 

1432 :paramref:`_schema.Column.unique` and 

1433 :paramref:`_schema.Column.index` flags to True simultaneously, 

1434 which will have the effect of rendering the "CREATE UNIQUE INDEX" 

1435 DDL instruction instead of "CREATE INDEX". 

1436 

1437 The name of the index is generated using the 

1438 :ref:`default naming convention <constraint_default_naming_convention>` 

1439 which for the :class:`_schema.Index` construct is of the form 

1440 ``ix_<tablename>_<columnname>``. 

1441 

1442 As this flag is intended only as a convenience for the common case 

1443 of adding a single-column, default configured index to a table 

1444 definition, explicit use of the :class:`_schema.Index` construct 

1445 should be preferred for most use cases, including composite indexes 

1446 that encompass more than one column, indexes with SQL expressions 

1447 or ordering, backend-specific index configuration options, and 

1448 indexes that use a specific name. 

1449 

1450 .. note:: the :attr:`_schema.Column.index` attribute on 

1451 :class:`_schema.Column` 

1452 **does not indicate** if this column is indexed or not, only 

1453 if this flag was explicitly set here. To view indexes on 

1454 a column, view the :attr:`_schema.Table.indexes` collection 

1455 or use :meth:`_reflection.Inspector.get_indexes`. 

1456 

1457 .. seealso:: 

1458 

1459 :ref:`schema_indexes` 

1460 

1461 :ref:`constraint_naming_conventions` 

1462 

1463 :paramref:`_schema.Column.unique` 

1464 

1465 :param info: Optional data dictionary which will be populated into the 

1466 :attr:`.SchemaItem.info` attribute of this object. 

1467 

1468 :param nullable: When set to ``False``, will cause the "NOT NULL" 

1469 phrase to be added when generating DDL for the column. When 

1470 ``True``, will normally generate nothing (in SQL this defaults to 

1471 "NULL"), except in some very specific backend-specific edge cases 

1472 where "NULL" may render explicitly. 

1473 Defaults to ``True`` unless :paramref:`_schema.Column.primary_key` 

1474 is also ``True`` or the column specifies a :class:`_sql.Identity`, 

1475 in which case it defaults to ``False``. 

1476 This parameter is only used when issuing CREATE TABLE statements. 

1477 

1478 .. note:: 

1479 

1480 When the column specifies a :class:`_sql.Identity` this 

1481 parameter is in general ignored by the DDL compiler. The 

1482 PostgreSQL database allows nullable identity column by 

1483 setting this parameter to ``True`` explicitly. 

1484 

1485 :param onupdate: A scalar, Python callable, or 

1486 :class:`~sqlalchemy.sql.expression.ClauseElement` representing a 

1487 default value to be applied to the column within UPDATE 

1488 statements, which will be invoked upon update if this column is not 

1489 present in the SET clause of the update. This is a shortcut to 

1490 using :class:`.ColumnDefault` as a positional argument with 

1491 ``for_update=True``. 

1492 

1493 .. seealso:: 

1494 

1495 :ref:`metadata_defaults` - complete discussion of onupdate 

1496 

1497 :param primary_key: If ``True``, marks this column as a primary key 

1498 column. Multiple columns can have this flag set to specify 

1499 composite primary keys. As an alternative, the primary key of a 

1500 :class:`_schema.Table` can be specified via an explicit 

1501 :class:`.PrimaryKeyConstraint` object. 

1502 

1503 :param server_default: A :class:`.FetchedValue` instance, str, Unicode 

1504 or :func:`~sqlalchemy.sql.expression.text` construct representing 

1505 the DDL DEFAULT value for the column. 

1506 

1507 String types will be emitted as-is, surrounded by single quotes:: 

1508 

1509 Column('x', Text, server_default="val") 

1510 

1511 x TEXT DEFAULT 'val' 

1512 

1513 A :func:`~sqlalchemy.sql.expression.text` expression will be 

1514 rendered as-is, without quotes:: 

1515 

1516 Column('y', DateTime, server_default=text('NOW()')) 

1517 

1518 y DATETIME DEFAULT NOW() 

1519 

1520 Strings and text() will be converted into a 

1521 :class:`.DefaultClause` object upon initialization. 

1522 

1523 This parameter can also accept complex combinations of contextually 

1524 valid SQLAlchemy expressions or constructs:: 

1525 

1526 from sqlalchemy import create_engine 

1527 from sqlalchemy import Table, Column, MetaData, ARRAY, Text 

1528 from sqlalchemy.dialects.postgresql import array 

1529 

1530 engine = create_engine( 

1531 'postgresql://scott:tiger@localhost/mydatabase' 

1532 ) 

1533 metadata_obj = MetaData() 

1534 tbl = Table( 

1535 "foo", 

1536 metadata_obj, 

1537 Column("bar", 

1538 ARRAY(Text), 

1539 server_default=array(["biz", "bang", "bash"]) 

1540 ) 

1541 ) 

1542 metadata_obj.create_all(engine) 

1543 

1544 The above results in a table created with the following SQL:: 

1545 

1546 CREATE TABLE foo ( 

1547 bar TEXT[] DEFAULT ARRAY['biz', 'bang', 'bash'] 

1548 ) 

1549 

1550 Use :class:`.FetchedValue` to indicate that an already-existing 

1551 column will generate a default value on the database side which 

1552 will be available to SQLAlchemy for post-fetch after inserts. This 

1553 construct does not specify any DDL and the implementation is left 

1554 to the database, such as via a trigger. 

1555 

1556 .. seealso:: 

1557 

1558 :ref:`server_defaults` - complete discussion of server side 

1559 defaults 

1560 

1561 :param server_onupdate: A :class:`.FetchedValue` instance 

1562 representing a database-side default generation function, 

1563 such as a trigger. This 

1564 indicates to SQLAlchemy that a newly generated value will be 

1565 available after updates. This construct does not actually 

1566 implement any kind of generation function within the database, 

1567 which instead must be specified separately. 

1568 

1569 

1570 .. warning:: This directive **does not** currently produce MySQL's 

1571 "ON UPDATE CURRENT_TIMESTAMP()" clause. See 

1572 :ref:`mysql_timestamp_onupdate` for background on how to 

1573 produce this clause. 

1574 

1575 .. seealso:: 

1576 

1577 :ref:`triggered_columns` 

1578 

1579 :param quote: Force quoting of this column's name on or off, 

1580 corresponding to ``True`` or ``False``. When left at its default 

1581 of ``None``, the column identifier will be quoted according to 

1582 whether the name is case sensitive (identifiers with at least one 

1583 upper case character are treated as case sensitive), or if it's a 

1584 reserved word. This flag is only needed to force quoting of a 

1585 reserved word which is not known by the SQLAlchemy dialect. 

1586 

1587 :param unique: When ``True``, and the :paramref:`_schema.Column.index` 

1588 parameter is left at its default value of ``False``, 

1589 indicates that a :class:`_schema.UniqueConstraint` 

1590 construct will be automatically generated for this 

1591 :class:`_schema.Column`, 

1592 which will result in a "UNIQUE CONSTRAINT" clause referring 

1593 to this column being included 

1594 in the ``CREATE TABLE`` statement emitted, when the DDL create 

1595 operation for the :class:`_schema.Table` object is invoked. 

1596 

1597 When this flag is ``True`` while the 

1598 :paramref:`_schema.Column.index` parameter is simultaneously 

1599 set to ``True``, the effect instead is that a 

1600 :class:`_schema.Index` construct which includes the 

1601 :paramref:`_schema.Index.unique` parameter set to ``True`` 

1602 is generated. See the documentation for 

1603 :paramref:`_schema.Column.index` for additional detail. 

1604 

1605 Using this flag is equivalent to making use of the 

1606 :class:`_schema.UniqueConstraint` construct explicitly at the 

1607 level of the :class:`_schema.Table` construct itself:: 

1608 

1609 Table( 

1610 "some_table", 

1611 metadata, 

1612 Column("x", Integer), 

1613 UniqueConstraint("x") 

1614 ) 

1615 

1616 The :paramref:`_schema.UniqueConstraint.name` parameter 

1617 of the unique constraint object is left at its default value 

1618 of ``None``; in the absence of a :ref:`naming convention <constraint_naming_conventions>` 

1619 for the enclosing :class:`_schema.MetaData`, the UNIQUE CONSTRAINT 

1620 construct will be emitted as unnamed, which typically invokes 

1621 a database-specific naming convention to take place. 

1622 

1623 As this flag is intended only as a convenience for the common case 

1624 of adding a single-column, default configured unique constraint to a table 

1625 definition, explicit use of the :class:`_schema.UniqueConstraint` construct 

1626 should be preferred for most use cases, including composite constraints 

1627 that encompass more than one column, backend-specific index configuration options, and 

1628 constraints that use a specific name. 

1629 

1630 .. note:: the :attr:`_schema.Column.unique` attribute on 

1631 :class:`_schema.Column` 

1632 **does not indicate** if this column has a unique constraint or 

1633 not, only if this flag was explicitly set here. To view 

1634 indexes and unique constraints that may involve this column, 

1635 view the 

1636 :attr:`_schema.Table.indexes` and/or 

1637 :attr:`_schema.Table.constraints` collections or use 

1638 :meth:`_reflection.Inspector.get_indexes` and/or 

1639 :meth:`_reflection.Inspector.get_unique_constraints` 

1640 

1641 .. seealso:: 

1642 

1643 :ref:`schema_unique_constraint` 

1644 

1645 :ref:`constraint_naming_conventions` 

1646 

1647 :paramref:`_schema.Column.index` 

1648 

1649 :param system: When ``True``, indicates this is a "system" column, 

1650 that is a column which is automatically made available by the 

1651 database, and should not be included in the columns list for a 

1652 ``CREATE TABLE`` statement. 

1653 

1654 For more elaborate scenarios where columns should be 

1655 conditionally rendered differently on different backends, 

1656 consider custom compilation rules for :class:`.CreateColumn`. 

1657 

1658 :param comment: Optional string that will render an SQL comment on 

1659 table creation. 

1660 

1661 .. versionadded:: 1.2 Added the 

1662 :paramref:`_schema.Column.comment` 

1663 parameter to :class:`_schema.Column`. 

1664 

1665 

1666 """ # noqa: E501, RST201, RST202 

1667 

1668 name = kwargs.pop("name", None) 

1669 type_ = kwargs.pop("type_", None) 

1670 args = list(args) 

1671 if args: 

1672 if isinstance(args[0], util.string_types): 

1673 if name is not None: 

1674 raise exc.ArgumentError( 

1675 "May not pass name positionally and as a keyword." 

1676 ) 

1677 name = args.pop(0) 

1678 if args: 

1679 coltype = args[0] 

1680 

1681 if hasattr(coltype, "_sqla_type"): 

1682 if type_ is not None: 

1683 raise exc.ArgumentError( 

1684 "May not pass type_ positionally and as a keyword." 

1685 ) 

1686 type_ = args.pop(0) 

1687 

1688 if name is not None: 

1689 name = quoted_name(name, kwargs.pop("quote", None)) 

1690 elif "quote" in kwargs: 

1691 raise exc.ArgumentError( 

1692 "Explicit 'name' is required when " "sending 'quote' argument" 

1693 ) 

1694 

1695 super(Column, self).__init__(name, type_) 

1696 self.key = kwargs.pop("key", name) 

1697 self.primary_key = primary_key = kwargs.pop("primary_key", False) 

1698 

1699 self._user_defined_nullable = udn = kwargs.pop( 

1700 "nullable", NULL_UNSPECIFIED 

1701 ) 

1702 

1703 if udn is not NULL_UNSPECIFIED: 

1704 self.nullable = udn 

1705 else: 

1706 self.nullable = not primary_key 

1707 

1708 self.default = kwargs.pop("default", None) 

1709 self.server_default = kwargs.pop("server_default", None) 

1710 self.server_onupdate = kwargs.pop("server_onupdate", None) 

1711 

1712 # these default to None because .index and .unique is *not* 

1713 # an informational flag about Column - there can still be an 

1714 # Index or UniqueConstraint referring to this Column. 

1715 self.index = kwargs.pop("index", None) 

1716 self.unique = kwargs.pop("unique", None) 

1717 

1718 self.system = kwargs.pop("system", False) 

1719 self.doc = kwargs.pop("doc", None) 

1720 self.onupdate = kwargs.pop("onupdate", None) 

1721 self.autoincrement = kwargs.pop("autoincrement", "auto") 

1722 self.constraints = set() 

1723 self.foreign_keys = set() 

1724 self.comment = kwargs.pop("comment", None) 

1725 self.computed = None 

1726 self.identity = None 

1727 

1728 # check if this Column is proxying another column 

1729 if "_proxies" in kwargs: 

1730 self._proxies = kwargs.pop("_proxies") 

1731 # otherwise, add DDL-related events 

1732 elif isinstance(self.type, SchemaEventTarget): 

1733 self.type._set_parent_with_dispatch(self) 

1734 

1735 if self.default is not None: 

1736 if isinstance(self.default, (ColumnDefault, Sequence)): 

1737 args.append(self.default) 

1738 else: 

1739 if getattr(self.type, "_warn_on_bytestring", False): 

1740 if isinstance(self.default, util.binary_type): 

1741 util.warn( 

1742 "Unicode column '%s' has non-unicode " 

1743 "default value %r specified." 

1744 % (self.key, self.default) 

1745 ) 

1746 args.append(ColumnDefault(self.default)) 

1747 

1748 if self.server_default is not None: 

1749 if isinstance(self.server_default, FetchedValue): 

1750 args.append(self.server_default._as_for_update(False)) 

1751 else: 

1752 args.append(DefaultClause(self.server_default)) 

1753 

1754 if self.onupdate is not None: 

1755 if isinstance(self.onupdate, (ColumnDefault, Sequence)): 

1756 args.append(self.onupdate) 

1757 else: 

1758 args.append(ColumnDefault(self.onupdate, for_update=True)) 

1759 

1760 if self.server_onupdate is not None: 

1761 if isinstance(self.server_onupdate, FetchedValue): 

1762 args.append(self.server_onupdate._as_for_update(True)) 

1763 else: 

1764 args.append( 

1765 DefaultClause(self.server_onupdate, for_update=True) 

1766 ) 

1767 self._init_items(*args) 

1768 

1769 util.set_creation_order(self) 

1770 

1771 if "info" in kwargs: 

1772 self.info = kwargs.pop("info") 

1773 

1774 self._extra_kwargs(**kwargs) 

1775 

1776 foreign_keys = None 

1777 """A collection of all :class:`_schema.ForeignKey` marker objects 

1778 associated with this :class:`_schema.Column`. 

1779 

1780 Each object is a member of a :class:`_schema.Table`-wide 

1781 :class:`_schema.ForeignKeyConstraint`. 

1782 

1783 .. seealso:: 

1784 

1785 :attr:`_schema.Table.foreign_keys` 

1786 

1787 """ 

1788 

1789 index = None 

1790 """The value of the :paramref:`_schema.Column.index` parameter. 

1791 

1792 Does not indicate if this :class:`_schema.Column` is actually indexed 

1793 or not; use :attr:`_schema.Table.indexes`. 

1794 

1795 .. seealso:: 

1796 

1797 :attr:`_schema.Table.indexes` 

1798 """ 

1799 

1800 unique = None 

1801 """The value of the :paramref:`_schema.Column.unique` parameter. 

1802 

1803 Does not indicate if this :class:`_schema.Column` is actually subject to 

1804 a unique constraint or not; use :attr:`_schema.Table.indexes` and 

1805 :attr:`_schema.Table.constraints`. 

1806 

1807 .. seealso:: 

1808 

1809 :attr:`_schema.Table.indexes` 

1810 

1811 :attr:`_schema.Table.constraints`. 

1812 

1813 """ 

1814 

1815 @util.memoized_property 

1816 def _gen_static_annotations_cache_key(self): 

1817 """special attribute used by cache key gen, if true, we will 

1818 use a static cache key for the annotations dictionary, else we 

1819 will generate a new cache key for annotations each time. 

1820 

1821 Added for #8790 

1822 

1823 """ 

1824 return self.table is not None and self.table._is_table 

1825 

1826 def _extra_kwargs(self, **kwargs): 

1827 self._validate_dialect_kwargs(kwargs) 

1828 

1829 def __str__(self): 

1830 if self.name is None: 

1831 return "(no name)" 

1832 elif self.table is not None: 

1833 if self.table.named_with_column: 

1834 return self.table.description + "." + self.description 

1835 else: 

1836 return self.description 

1837 else: 

1838 return self.description 

1839 

1840 def references(self, column): 

1841 """Return True if this Column references the given column via foreign 

1842 key.""" 

1843 

1844 for fk in self.foreign_keys: 

1845 if fk.column.proxy_set.intersection(column.proxy_set): 

1846 return True 

1847 else: 

1848 return False 

1849 

1850 def append_foreign_key(self, fk): 

1851 fk._set_parent_with_dispatch(self) 

1852 

1853 def __repr__(self): 

1854 kwarg = [] 

1855 if self.key != self.name: 

1856 kwarg.append("key") 

1857 if self.primary_key: 

1858 kwarg.append("primary_key") 

1859 if not self.nullable: 

1860 kwarg.append("nullable") 

1861 if self.onupdate: 

1862 kwarg.append("onupdate") 

1863 if self.default: 

1864 kwarg.append("default") 

1865 if self.server_default: 

1866 kwarg.append("server_default") 

1867 if self.comment: 

1868 kwarg.append("comment") 

1869 return "Column(%s)" % ", ".join( 

1870 [repr(self.name)] 

1871 + [repr(self.type)] 

1872 + [repr(x) for x in self.foreign_keys if x is not None] 

1873 + [repr(x) for x in self.constraints] 

1874 + [ 

1875 ( 

1876 self.table is not None 

1877 and "table=<%s>" % self.table.description 

1878 or "table=None" 

1879 ) 

1880 ] 

1881 + ["%s=%s" % (k, repr(getattr(self, k))) for k in kwarg] 

1882 ) 

1883 

1884 def _set_parent(self, table, allow_replacements=True): 

1885 if not self.name: 

1886 raise exc.ArgumentError( 

1887 "Column must be constructed with a non-blank name or " 

1888 "assign a non-blank .name before adding to a Table." 

1889 ) 

1890 

1891 self._reset_memoizations() 

1892 

1893 if self.key is None: 

1894 self.key = self.name 

1895 

1896 existing = getattr(self, "table", None) 

1897 if existing is not None and existing is not table: 

1898 raise exc.ArgumentError( 

1899 "Column object '%s' already assigned to Table '%s'" 

1900 % (self.key, existing.description) 

1901 ) 

1902 

1903 if self.key in table._columns: 

1904 col = table._columns.get(self.key) 

1905 if col is not self: 

1906 if not allow_replacements: 

1907 util.warn_deprecated( 

1908 "A column with name '%s' is already present " 

1909 "in table '%s'. Please use method " 

1910 ":meth:`_schema.Table.append_column` with the " 

1911 "parameter ``replace_existing=True`` to replace an " 

1912 "existing column." % (self.key, table.name), 

1913 "1.4", 

1914 ) 

1915 for fk in col.foreign_keys: 

1916 table.foreign_keys.remove(fk) 

1917 if fk.constraint in table.constraints: 

1918 # this might have been removed 

1919 # already, if it's a composite constraint 

1920 # and more than one col being replaced 

1921 table.constraints.remove(fk.constraint) 

1922 

1923 table._columns.replace(self) 

1924 

1925 self.table = table 

1926 

1927 if self.primary_key: 

1928 table.primary_key._replace(self) 

1929 elif self.key in table.primary_key: 

1930 raise exc.ArgumentError( 

1931 "Trying to redefine primary-key column '%s' as a " 

1932 "non-primary-key column on table '%s'" 

1933 % (self.key, table.fullname) 

1934 ) 

1935 

1936 if self.index: 

1937 if isinstance(self.index, util.string_types): 

1938 raise exc.ArgumentError( 

1939 "The 'index' keyword argument on Column is boolean only. " 

1940 "To create indexes with a specific name, create an " 

1941 "explicit Index object external to the Table." 

1942 ) 

1943 table.append_constraint( 

1944 Index( 

1945 None, self.key, unique=bool(self.unique), _column_flag=True 

1946 ) 

1947 ) 

1948 

1949 elif self.unique: 

1950 if isinstance(self.unique, util.string_types): 

1951 raise exc.ArgumentError( 

1952 "The 'unique' keyword argument on Column is boolean " 

1953 "only. To create unique constraints or indexes with a " 

1954 "specific name, append an explicit UniqueConstraint to " 

1955 "the Table's list of elements, or create an explicit " 

1956 "Index object external to the Table." 

1957 ) 

1958 table.append_constraint( 

1959 UniqueConstraint(self.key, _column_flag=True) 

1960 ) 

1961 

1962 self._setup_on_memoized_fks(lambda fk: fk._set_remote_table(table)) 

1963 

1964 if self.identity and ( 

1965 isinstance(self.default, Sequence) 

1966 or isinstance(self.onupdate, Sequence) 

1967 ): 

1968 raise exc.ArgumentError( 

1969 "An column cannot specify both Identity and Sequence." 

1970 ) 

1971 

1972 def _setup_on_memoized_fks(self, fn): 

1973 fk_keys = [ 

1974 ((self.table.key, self.key), False), 

1975 ((self.table.key, self.name), True), 

1976 ] 

1977 for fk_key, link_to_name in fk_keys: 

1978 if fk_key in self.table.metadata._fk_memos: 

1979 for fk in self.table.metadata._fk_memos[fk_key]: 

1980 if fk.link_to_name is link_to_name: 

1981 fn(fk) 

1982 

1983 def _on_table_attach(self, fn): 

1984 if self.table is not None: 

1985 fn(self, self.table) 

1986 else: 

1987 event.listen(self, "after_parent_attach", fn) 

1988 

1989 @util.deprecated( 

1990 "1.4", 

1991 "The :meth:`_schema.Column.copy` method is deprecated " 

1992 "and will be removed in a future release.", 

1993 ) 

1994 def copy(self, **kw): 

1995 return self._copy(**kw) 

1996 

1997 def _copy(self, **kw): 

1998 """Create a copy of this ``Column``, uninitialized. 

1999 

2000 This is used in :meth:`_schema.Table.to_metadata`. 

2001 

2002 """ 

2003 

2004 # Constraint objects plus non-constraint-bound ForeignKey objects 

2005 args = [ 

2006 c._copy(**kw) for c in self.constraints if not c._type_bound 

2007 ] + [c._copy(**kw) for c in self.foreign_keys if not c.constraint] 

2008 

2009 # ticket #5276 

2010 column_kwargs = {} 

2011 for dialect_name in self.dialect_options: 

2012 dialect_options = self.dialect_options[dialect_name]._non_defaults 

2013 for ( 

2014 dialect_option_key, 

2015 dialect_option_value, 

2016 ) in dialect_options.items(): 

2017 column_kwargs[ 

2018 dialect_name + "_" + dialect_option_key 

2019 ] = dialect_option_value 

2020 

2021 server_default = self.server_default 

2022 server_onupdate = self.server_onupdate 

2023 if isinstance(server_default, (Computed, Identity)): 

2024 server_default = server_onupdate = None 

2025 args.append(self.server_default._copy(**kw)) 

2026 

2027 type_ = self.type 

2028 if isinstance(type_, SchemaEventTarget): 

2029 type_ = type_.copy(**kw) 

2030 

2031 if self._user_defined_nullable is not NULL_UNSPECIFIED: 

2032 column_kwargs["nullable"] = self._user_defined_nullable 

2033 

2034 c = self._constructor( 

2035 name=self.name, 

2036 type_=type_, 

2037 key=self.key, 

2038 primary_key=self.primary_key, 

2039 unique=self.unique, 

2040 system=self.system, 

2041 # quote=self.quote, # disabled 2013-08-27 (commit 031ef080) 

2042 index=self.index, 

2043 autoincrement=self.autoincrement, 

2044 default=self.default, 

2045 server_default=server_default, 

2046 onupdate=self.onupdate, 

2047 server_onupdate=server_onupdate, 

2048 doc=self.doc, 

2049 comment=self.comment, 

2050 *args, 

2051 **column_kwargs 

2052 ) 

2053 return self._schema_item_copy(c) 

2054 

2055 def _make_proxy( 

2056 self, selectable, name=None, key=None, name_is_truncatable=False, **kw 

2057 ): 

2058 """Create a *proxy* for this column. 

2059 

2060 This is a copy of this ``Column`` referenced by a different parent 

2061 (such as an alias or select statement). The column should 

2062 be used only in select scenarios, as its full DDL/default 

2063 information is not transferred. 

2064 

2065 """ 

2066 

2067 fk = [ 

2068 ForeignKey( 

2069 col if col is not None else f._colspec, 

2070 _unresolvable=col is None, 

2071 _constraint=f.constraint, 

2072 ) 

2073 for f, col in [ 

2074 (fk, fk._resolve_column(raiseerr=False)) 

2075 for fk in self.foreign_keys 

2076 ] 

2077 ] 

2078 

2079 if name is None and self.name is None: 

2080 raise exc.InvalidRequestError( 

2081 "Cannot initialize a sub-selectable" 

2082 " with this Column object until its 'name' has " 

2083 "been assigned." 

2084 ) 

2085 try: 

2086 c = self._constructor( 

2087 coercions.expect( 

2088 roles.TruncatedLabelRole, name if name else self.name 

2089 ) 

2090 if name_is_truncatable 

2091 else (name or self.name), 

2092 self.type, 

2093 # this may actually be ._proxy_key when the key is incoming 

2094 key=key if key else name if name else self.key, 

2095 primary_key=self.primary_key, 

2096 nullable=self.nullable, 

2097 _proxies=[self], 

2098 *fk 

2099 ) 

2100 except TypeError as err: 

2101 util.raise_( 

2102 TypeError( 

2103 "Could not create a copy of this %r object. " 

2104 "Ensure the class includes a _constructor() " 

2105 "attribute or method which accepts the " 

2106 "standard Column constructor arguments, or " 

2107 "references the Column class itself." % self.__class__ 

2108 ), 

2109 from_=err, 

2110 ) 

2111 

2112 c.table = selectable 

2113 c._propagate_attrs = selectable._propagate_attrs 

2114 if selectable._is_clone_of is not None: 

2115 c._is_clone_of = selectable._is_clone_of.columns.get(c.key) 

2116 if self.primary_key: 

2117 selectable.primary_key.add(c) 

2118 if fk: 

2119 selectable.foreign_keys.update(fk) 

2120 return c.key, c 

2121 

2122 

2123class ForeignKey(DialectKWArgs, SchemaItem): 

2124 """Defines a dependency between two columns. 

2125 

2126 ``ForeignKey`` is specified as an argument to a :class:`_schema.Column` 

2127 object, 

2128 e.g.:: 

2129 

2130 t = Table("remote_table", metadata, 

2131 Column("remote_id", ForeignKey("main_table.id")) 

2132 ) 

2133 

2134 Note that ``ForeignKey`` is only a marker object that defines 

2135 a dependency between two columns. The actual constraint 

2136 is in all cases represented by the :class:`_schema.ForeignKeyConstraint` 

2137 object. This object will be generated automatically when 

2138 a ``ForeignKey`` is associated with a :class:`_schema.Column` which 

2139 in turn is associated with a :class:`_schema.Table`. Conversely, 

2140 when :class:`_schema.ForeignKeyConstraint` is applied to a 

2141 :class:`_schema.Table`, 

2142 ``ForeignKey`` markers are automatically generated to be 

2143 present on each associated :class:`_schema.Column`, which are also 

2144 associated with the constraint object. 

2145 

2146 Note that you cannot define a "composite" foreign key constraint, 

2147 that is a constraint between a grouping of multiple parent/child 

2148 columns, using ``ForeignKey`` objects. To define this grouping, 

2149 the :class:`_schema.ForeignKeyConstraint` object must be used, and applied 

2150 to the :class:`_schema.Table`. The associated ``ForeignKey`` objects 

2151 are created automatically. 

2152 

2153 The ``ForeignKey`` objects associated with an individual 

2154 :class:`_schema.Column` 

2155 object are available in the `foreign_keys` collection 

2156 of that column. 

2157 

2158 Further examples of foreign key configuration are in 

2159 :ref:`metadata_foreignkeys`. 

2160 

2161 """ 

2162 

2163 __visit_name__ = "foreign_key" 

2164 

2165 def __init__( 

2166 self, 

2167 column, 

2168 _constraint=None, 

2169 use_alter=False, 

2170 name=None, 

2171 onupdate=None, 

2172 ondelete=None, 

2173 deferrable=None, 

2174 initially=None, 

2175 link_to_name=False, 

2176 match=None, 

2177 info=None, 

2178 _unresolvable=False, 

2179 **dialect_kw 

2180 ): 

2181 r""" 

2182 Construct a column-level FOREIGN KEY. 

2183 

2184 The :class:`_schema.ForeignKey` object when constructed generates a 

2185 :class:`_schema.ForeignKeyConstraint` 

2186 which is associated with the parent 

2187 :class:`_schema.Table` object's collection of constraints. 

2188 

2189 :param column: A single target column for the key relationship. A 

2190 :class:`_schema.Column` object or a column name as a string: 

2191 ``tablename.columnkey`` or ``schema.tablename.columnkey``. 

2192 ``columnkey`` is the ``key`` which has been assigned to the column 

2193 (defaults to the column name itself), unless ``link_to_name`` is 

2194 ``True`` in which case the rendered name of the column is used. 

2195 

2196 :param name: Optional string. An in-database name for the key if 

2197 `constraint` is not provided. 

2198 

2199 :param onupdate: Optional string. If set, emit ON UPDATE <value> when 

2200 issuing DDL for this constraint. Typical values include CASCADE, 

2201 DELETE and RESTRICT. 

2202 

2203 :param ondelete: Optional string. If set, emit ON DELETE <value> when 

2204 issuing DDL for this constraint. Typical values include CASCADE, 

2205 DELETE and RESTRICT. 

2206 

2207 :param deferrable: Optional bool. If set, emit DEFERRABLE or NOT 

2208 DEFERRABLE when issuing DDL for this constraint. 

2209 

2210 :param initially: Optional string. If set, emit INITIALLY <value> when 

2211 issuing DDL for this constraint. 

2212 

2213 :param link_to_name: if True, the string name given in ``column`` is 

2214 the rendered name of the referenced column, not its locally 

2215 assigned ``key``. 

2216 

2217 :param use_alter: passed to the underlying 

2218 :class:`_schema.ForeignKeyConstraint` 

2219 to indicate the constraint should 

2220 be generated/dropped externally from the CREATE TABLE/ DROP TABLE 

2221 statement. See :paramref:`_schema.ForeignKeyConstraint.use_alter` 

2222 for further description. 

2223 

2224 .. seealso:: 

2225 

2226 :paramref:`_schema.ForeignKeyConstraint.use_alter` 

2227 

2228 :ref:`use_alter` 

2229 

2230 :param match: Optional string. If set, emit MATCH <value> when issuing 

2231 DDL for this constraint. Typical values include SIMPLE, PARTIAL 

2232 and FULL. 

2233 

2234 :param info: Optional data dictionary which will be populated into the 

2235 :attr:`.SchemaItem.info` attribute of this object. 

2236 

2237 .. versionadded:: 1.0.0 

2238 

2239 :param \**dialect_kw: Additional keyword arguments are dialect 

2240 specific, and passed in the form ``<dialectname>_<argname>``. The 

2241 arguments are ultimately handled by a corresponding 

2242 :class:`_schema.ForeignKeyConstraint`. 

2243 See the documentation regarding 

2244 an individual dialect at :ref:`dialect_toplevel` for detail on 

2245 documented arguments. 

2246 

2247 .. versionadded:: 0.9.2 

2248 

2249 """ 

2250 

2251 self._colspec = coercions.expect(roles.DDLReferredColumnRole, column) 

2252 self._unresolvable = _unresolvable 

2253 

2254 if isinstance(self._colspec, util.string_types): 

2255 self._table_column = None 

2256 else: 

2257 self._table_column = self._colspec 

2258 

2259 if not isinstance( 

2260 self._table_column.table, (util.NoneType, TableClause) 

2261 ): 

2262 raise exc.ArgumentError( 

2263 "ForeignKey received Column not bound " 

2264 "to a Table, got: %r" % self._table_column.table 

2265 ) 

2266 

2267 # the linked ForeignKeyConstraint. 

2268 # ForeignKey will create this when parent Column 

2269 # is attached to a Table, *or* ForeignKeyConstraint 

2270 # object passes itself in when creating ForeignKey 

2271 # markers. 

2272 self.constraint = _constraint 

2273 self.parent = None 

2274 self.use_alter = use_alter 

2275 self.name = name 

2276 self.onupdate = onupdate 

2277 self.ondelete = ondelete 

2278 self.deferrable = deferrable 

2279 self.initially = initially 

2280 self.link_to_name = link_to_name 

2281 self.match = match 

2282 if info: 

2283 self.info = info 

2284 self._unvalidated_dialect_kw = dialect_kw 

2285 

2286 def __repr__(self): 

2287 return "ForeignKey(%r)" % self._get_colspec() 

2288 

2289 @util.deprecated( 

2290 "1.4", 

2291 "The :meth:`_schema.ForeignKey.copy` method is deprecated " 

2292 "and will be removed in a future release.", 

2293 ) 

2294 def copy(self, schema=None, **kw): 

2295 return self._copy(schema=schema, **kw) 

2296 

2297 def _copy(self, schema=None, **kw): 

2298 """Produce a copy of this :class:`_schema.ForeignKey` object. 

2299 

2300 The new :class:`_schema.ForeignKey` will not be bound 

2301 to any :class:`_schema.Column`. 

2302 

2303 This method is usually used by the internal 

2304 copy procedures of :class:`_schema.Column`, :class:`_schema.Table`, 

2305 and :class:`_schema.MetaData`. 

2306 

2307 :param schema: The returned :class:`_schema.ForeignKey` will 

2308 reference the original table and column name, qualified 

2309 by the given string schema name. 

2310 

2311 """ 

2312 

2313 fk = ForeignKey( 

2314 self._get_colspec(schema=schema), 

2315 use_alter=self.use_alter, 

2316 name=self.name, 

2317 onupdate=self.onupdate, 

2318 ondelete=self.ondelete, 

2319 deferrable=self.deferrable, 

2320 initially=self.initially, 

2321 link_to_name=self.link_to_name, 

2322 match=self.match, 

2323 **self._unvalidated_dialect_kw 

2324 ) 

2325 return self._schema_item_copy(fk) 

2326 

2327 def _get_colspec(self, schema=None, table_name=None): 

2328 """Return a string based 'column specification' for this 

2329 :class:`_schema.ForeignKey`. 

2330 

2331 This is usually the equivalent of the string-based "tablename.colname" 

2332 argument first passed to the object's constructor. 

2333 

2334 """ 

2335 if schema not in (None, RETAIN_SCHEMA): 

2336 _schema, tname, colname = self._column_tokens 

2337 if table_name is not None: 

2338 tname = table_name 

2339 if schema is BLANK_SCHEMA: 

2340 return "%s.%s" % (tname, colname) 

2341 else: 

2342 return "%s.%s.%s" % (schema, tname, colname) 

2343 elif table_name: 

2344 schema, tname, colname = self._column_tokens 

2345 if schema: 

2346 return "%s.%s.%s" % (schema, table_name, colname) 

2347 else: 

2348 return "%s.%s" % (table_name, colname) 

2349 elif self._table_column is not None: 

2350 return "%s.%s" % ( 

2351 self._table_column.table.fullname, 

2352 self._table_column.key, 

2353 ) 

2354 else: 

2355 return self._colspec 

2356 

2357 @property 

2358 def _referred_schema(self): 

2359 return self._column_tokens[0] 

2360 

2361 def _table_key(self): 

2362 if self._table_column is not None: 

2363 if self._table_column.table is None: 

2364 return None 

2365 else: 

2366 return self._table_column.table.key 

2367 else: 

2368 schema, tname, colname = self._column_tokens 

2369 return _get_table_key(tname, schema) 

2370 

2371 target_fullname = property(_get_colspec) 

2372 

2373 def references(self, table): 

2374 """Return True if the given :class:`_schema.Table` 

2375 is referenced by this 

2376 :class:`_schema.ForeignKey`.""" 

2377 

2378 return table.corresponding_column(self.column) is not None 

2379 

2380 def get_referent(self, table): 

2381 """Return the :class:`_schema.Column` in the given 

2382 :class:`_schema.Table` 

2383 referenced by this :class:`_schema.ForeignKey`. 

2384 

2385 Returns None if this :class:`_schema.ForeignKey` 

2386 does not reference the given 

2387 :class:`_schema.Table`. 

2388 

2389 """ 

2390 

2391 return table.corresponding_column(self.column) 

2392 

2393 @util.memoized_property 

2394 def _column_tokens(self): 

2395 """parse a string-based _colspec into its component parts.""" 

2396 

2397 m = self._get_colspec().split(".") 

2398 if m is None: 

2399 raise exc.ArgumentError( 

2400 "Invalid foreign key column specification: %s" % self._colspec 

2401 ) 

2402 if len(m) == 1: 

2403 tname = m.pop() 

2404 colname = None 

2405 else: 

2406 colname = m.pop() 

2407 tname = m.pop() 

2408 

2409 # A FK between column 'bar' and table 'foo' can be 

2410 # specified as 'foo', 'foo.bar', 'dbo.foo.bar', 

2411 # 'otherdb.dbo.foo.bar'. Once we have the column name and 

2412 # the table name, treat everything else as the schema 

2413 # name. Some databases (e.g. Sybase) support 

2414 # inter-database foreign keys. See tickets#1341 and -- 

2415 # indirectly related -- Ticket #594. This assumes that '.' 

2416 # will never appear *within* any component of the FK. 

2417 

2418 if len(m) > 0: 

2419 schema = ".".join(m) 

2420 else: 

2421 schema = None 

2422 return schema, tname, colname 

2423 

2424 def _resolve_col_tokens(self): 

2425 if self.parent is None: 

2426 raise exc.InvalidRequestError( 

2427 "this ForeignKey object does not yet have a " 

2428 "parent Column associated with it." 

2429 ) 

2430 

2431 elif self.parent.table is None: 

2432 raise exc.InvalidRequestError( 

2433 "this ForeignKey's parent column is not yet associated " 

2434 "with a Table." 

2435 ) 

2436 

2437 parenttable = self.parent.table 

2438 

2439 if self._unresolvable: 

2440 schema, tname, colname = self._column_tokens 

2441 tablekey = _get_table_key(tname, schema) 

2442 return parenttable, tablekey, colname 

2443 

2444 # assertion 

2445 # basically Column._make_proxy() sends the actual 

2446 # target Column to the ForeignKey object, so the 

2447 # string resolution here is never called. 

2448 for c in self.parent.base_columns: 

2449 if isinstance(c, Column): 

2450 assert c.table is parenttable 

2451 break 

2452 else: 

2453 assert False 

2454 ###################### 

2455 

2456 schema, tname, colname = self._column_tokens 

2457 

2458 if schema is None and parenttable.metadata.schema is not None: 

2459 schema = parenttable.metadata.schema 

2460 

2461 tablekey = _get_table_key(tname, schema) 

2462 return parenttable, tablekey, colname 

2463 

2464 def _link_to_col_by_colstring(self, parenttable, table, colname): 

2465 

2466 _column = None 

2467 if colname is None: 

2468 # colname is None in the case that ForeignKey argument 

2469 # was specified as table name only, in which case we 

2470 # match the column name to the same column on the 

2471 # parent. 

2472 # this use case wasn't working in later 1.x series 

2473 # as it had no test coverage; fixed in 2.0 

2474 parent = self.parent 

2475 assert parent is not None 

2476 key = parent.key 

2477 _column = table.c.get(key, None) 

2478 elif self.link_to_name: 

2479 key = colname 

2480 for c in table.c: 

2481 if c.name == colname: 

2482 _column = c 

2483 else: 

2484 key = colname 

2485 _column = table.c.get(colname, None) 

2486 

2487 if _column is None: 

2488 raise exc.NoReferencedColumnError( 

2489 "Could not initialize target column " 

2490 "for ForeignKey '%s' on table '%s': " 

2491 "table '%s' has no column named '%s'" 

2492 % (self._colspec, parenttable.name, table.name, key), 

2493 table.name, 

2494 key, 

2495 ) 

2496 

2497 return _column 

2498 

2499 def _set_target_column(self, column): 

2500 assert self.parent is not None 

2501 

2502 # propagate TypeEngine to parent if it didn't have one 

2503 if self.parent.type._isnull: 

2504 self.parent.type = column.type 

2505 

2506 # super-edgy case, if other FKs point to our column, 

2507 # they'd get the type propagated out also. 

2508 

2509 def set_type(fk): 

2510 if fk.parent.type._isnull: 

2511 fk.parent.type = column.type 

2512 

2513 self.parent._setup_on_memoized_fks(set_type) 

2514 

2515 self.column = column 

2516 

2517 @util.memoized_property 

2518 def column(self): 

2519 """Return the target :class:`_schema.Column` referenced by this 

2520 :class:`_schema.ForeignKey`. 

2521 

2522 If no target column has been established, an exception 

2523 is raised. 

2524 

2525 .. versionchanged:: 0.9.0 

2526 Foreign key target column resolution now occurs as soon as both 

2527 the ForeignKey object and the remote Column to which it refers 

2528 are both associated with the same MetaData object. 

2529 

2530 """ 

2531 

2532 return self._resolve_column() 

2533 

2534 def _resolve_column(self, raiseerr=True): 

2535 

2536 if isinstance(self._colspec, util.string_types): 

2537 

2538 parenttable, tablekey, colname = self._resolve_col_tokens() 

2539 

2540 if self._unresolvable or tablekey not in parenttable.metadata: 

2541 if not raiseerr: 

2542 return None 

2543 raise exc.NoReferencedTableError( 

2544 "Foreign key associated with column '%s' could not find " 

2545 "table '%s' with which to generate a " 

2546 "foreign key to target column '%s'" 

2547 % (self.parent, tablekey, colname), 

2548 tablekey, 

2549 ) 

2550 elif parenttable.key not in parenttable.metadata: 

2551 if not raiseerr: 

2552 return None 

2553 raise exc.InvalidRequestError( 

2554 "Table %s is no longer associated with its " 

2555 "parent MetaData" % parenttable 

2556 ) 

2557 else: 

2558 table = parenttable.metadata.tables[tablekey] 

2559 return self._link_to_col_by_colstring( 

2560 parenttable, table, colname 

2561 ) 

2562 

2563 elif hasattr(self._colspec, "__clause_element__"): 

2564 _column = self._colspec.__clause_element__() 

2565 return _column 

2566 else: 

2567 _column = self._colspec 

2568 return _column 

2569 

2570 def _set_parent(self, column, **kw): 

2571 if self.parent is not None and self.parent is not column: 

2572 raise exc.InvalidRequestError( 

2573 "This ForeignKey already has a parent !" 

2574 ) 

2575 self.parent = column 

2576 self.parent.foreign_keys.add(self) 

2577 self.parent._on_table_attach(self._set_table) 

2578 

2579 def _set_remote_table(self, table): 

2580 parenttable, tablekey, colname = self._resolve_col_tokens() 

2581 self._link_to_col_by_colstring(parenttable, table, colname) 

2582 

2583 _column = self._link_to_col_by_colstring(parenttable, table, colname) 

2584 self._set_target_column(_column) 

2585 assert self.constraint is not None 

2586 

2587 self.constraint._validate_dest_table(table) 

2588 

2589 def _remove_from_metadata(self, metadata): 

2590 parenttable, table_key, colname = self._resolve_col_tokens() 

2591 fk_key = (table_key, colname) 

2592 

2593 if self in metadata._fk_memos[fk_key]: 

2594 # TODO: no test coverage for self not in memos 

2595 metadata._fk_memos[fk_key].remove(self) 

2596 

2597 def _set_table(self, column, table): 

2598 # standalone ForeignKey - create ForeignKeyConstraint 

2599 # on the hosting Table when attached to the Table. 

2600 assert isinstance(table, Table) 

2601 if self.constraint is None: 

2602 self.constraint = ForeignKeyConstraint( 

2603 [], 

2604 [], 

2605 use_alter=self.use_alter, 

2606 name=self.name, 

2607 onupdate=self.onupdate, 

2608 ondelete=self.ondelete, 

2609 deferrable=self.deferrable, 

2610 initially=self.initially, 

2611 match=self.match, 

2612 **self._unvalidated_dialect_kw 

2613 ) 

2614 self.constraint._append_element(column, self) 

2615 self.constraint._set_parent_with_dispatch(table) 

2616 table.foreign_keys.add(self) 

2617 # set up remote ".column" attribute, or a note to pick it 

2618 # up when the other Table/Column shows up 

2619 if isinstance(self._colspec, util.string_types): 

2620 parenttable, table_key, colname = self._resolve_col_tokens() 

2621 fk_key = (table_key, colname) 

2622 if table_key in parenttable.metadata.tables: 

2623 table = parenttable.metadata.tables[table_key] 

2624 try: 

2625 _column = self._link_to_col_by_colstring( 

2626 parenttable, table, colname 

2627 ) 

2628 except exc.NoReferencedColumnError: 

2629 # this is OK, we'll try later 

2630 pass 

2631 else: 

2632 self._set_target_column(_column) 

2633 parenttable.metadata._fk_memos[fk_key].append(self) 

2634 elif hasattr(self._colspec, "__clause_element__"): 

2635 _column = self._colspec.__clause_element__() 

2636 self._set_target_column(_column) 

2637 else: 

2638 _column = self._colspec 

2639 self._set_target_column(_column) 

2640 

2641 

2642class DefaultGenerator(Executable, SchemaItem): 

2643 """Base class for column *default* values.""" 

2644 

2645 __visit_name__ = "default_generator" 

2646 

2647 is_sequence = False 

2648 is_server_default = False 

2649 column = None 

2650 

2651 def __init__(self, for_update=False): 

2652 self.for_update = for_update 

2653 

2654 def _set_parent(self, column, **kw): 

2655 self.column = column 

2656 if self.for_update: 

2657 self.column.onupdate = self 

2658 else: 

2659 self.column.default = self 

2660 

2661 @util.deprecated_20( 

2662 ":meth:`.DefaultGenerator.execute`", 

2663 alternative="All statement execution in SQLAlchemy 2.0 is performed " 

2664 "by the :meth:`_engine.Connection.execute` method of " 

2665 ":class:`_engine.Connection`, " 

2666 "or in the ORM by the :meth:`.Session.execute` method of " 

2667 ":class:`.Session`.", 

2668 ) 

2669 def execute(self, bind=None): 

2670 if bind is None: 

2671 bind = _bind_or_error(self) 

2672 return bind._execute_default(self, (), util.EMPTY_DICT) 

2673 

2674 def _execute_on_connection( 

2675 self, connection, multiparams, params, execution_options 

2676 ): 

2677 return connection._execute_default( 

2678 self, multiparams, params, execution_options 

2679 ) 

2680 

2681 @property 

2682 def bind(self): 

2683 """Return the connectable associated with this default.""" 

2684 if getattr(self, "column", None) is not None: 

2685 return self.column.table.bind 

2686 else: 

2687 return None 

2688 

2689 

2690class ColumnDefault(DefaultGenerator): 

2691 """A plain default value on a column. 

2692 

2693 This could correspond to a constant, a callable function, 

2694 or a SQL clause. 

2695 

2696 :class:`.ColumnDefault` is generated automatically 

2697 whenever the ``default``, ``onupdate`` arguments of 

2698 :class:`_schema.Column` are used. A :class:`.ColumnDefault` 

2699 can be passed positionally as well. 

2700 

2701 For example, the following:: 

2702 

2703 Column('foo', Integer, default=50) 

2704 

2705 Is equivalent to:: 

2706 

2707 Column('foo', Integer, ColumnDefault(50)) 

2708 

2709 

2710 """ 

2711 

2712 def __init__(self, arg, **kwargs): 

2713 """Construct a new :class:`.ColumnDefault`. 

2714 

2715 

2716 :param arg: argument representing the default value. 

2717 May be one of the following: 

2718 

2719 * a plain non-callable Python value, such as a 

2720 string, integer, boolean, or other simple type. 

2721 The default value will be used as is each time. 

2722 * a SQL expression, that is one which derives from 

2723 :class:`_expression.ColumnElement`. The SQL expression will 

2724 be rendered into the INSERT or UPDATE statement, 

2725 or in the case of a primary key column when 

2726 RETURNING is not used may be 

2727 pre-executed before an INSERT within a SELECT. 

2728 * A Python callable. The function will be invoked for each 

2729 new row subject to an INSERT or UPDATE. 

2730 The callable must accept exactly 

2731 zero or one positional arguments. The one-argument form 

2732 will receive an instance of the :class:`.ExecutionContext`, 

2733 which provides contextual information as to the current 

2734 :class:`_engine.Connection` in use as well as the current 

2735 statement and parameters. 

2736 

2737 """ 

2738 super(ColumnDefault, self).__init__(**kwargs) 

2739 if isinstance(arg, FetchedValue): 

2740 raise exc.ArgumentError( 

2741 "ColumnDefault may not be a server-side default type." 

2742 ) 

2743 if callable(arg): 

2744 arg = self._maybe_wrap_callable(arg) 

2745 self.arg = arg 

2746 

2747 @util.memoized_property 

2748 def is_callable(self): 

2749 return callable(self.arg) 

2750 

2751 @util.memoized_property 

2752 def is_clause_element(self): 

2753 return isinstance(self.arg, ClauseElement) 

2754 

2755 @util.memoized_property 

2756 def is_scalar(self): 

2757 return ( 

2758 not self.is_callable 

2759 and not self.is_clause_element 

2760 and not self.is_sequence 

2761 ) 

2762 

2763 @util.memoized_property 

2764 @util.preload_module("sqlalchemy.sql.sqltypes") 

2765 def _arg_is_typed(self): 

2766 sqltypes = util.preloaded.sql_sqltypes 

2767 

2768 if self.is_clause_element: 

2769 return not isinstance(self.arg.type, sqltypes.NullType) 

2770 else: 

2771 return False 

2772 

2773 def _maybe_wrap_callable(self, fn): 

2774 """Wrap callables that don't accept a context. 

2775 

2776 This is to allow easy compatibility with default callables 

2777 that aren't specific to accepting of a context. 

2778 

2779 """ 

2780 try: 

2781 argspec = util.get_callable_argspec(fn, no_self=True) 

2782 except TypeError: 

2783 return util.wrap_callable(lambda ctx: fn(), fn) 

2784 

2785 defaulted = argspec[3] is not None and len(argspec[3]) or 0 

2786 positionals = len(argspec[0]) - defaulted 

2787 

2788 if positionals == 0: 

2789 return util.wrap_callable(lambda ctx: fn(), fn) 

2790 

2791 elif positionals == 1: 

2792 return fn 

2793 else: 

2794 raise exc.ArgumentError( 

2795 "ColumnDefault Python function takes zero or one " 

2796 "positional arguments" 

2797 ) 

2798 

2799 def __repr__(self): 

2800 return "ColumnDefault(%r)" % (self.arg,) 

2801 

2802 

2803class IdentityOptions(object): 

2804 """Defines options for a named database sequence or an identity column. 

2805 

2806 .. versionadded:: 1.3.18 

2807 

2808 .. seealso:: 

2809 

2810 :class:`.Sequence` 

2811 

2812 """ 

2813 

2814 def __init__( 

2815 self, 

2816 start=None, 

2817 increment=None, 

2818 minvalue=None, 

2819 maxvalue=None, 

2820 nominvalue=None, 

2821 nomaxvalue=None, 

2822 cycle=None, 

2823 cache=None, 

2824 order=None, 

2825 ): 

2826 """Construct a :class:`.IdentityOptions` object. 

2827 

2828 See the :class:`.Sequence` documentation for a complete description 

2829 of the parameters. 

2830 

2831 :param start: the starting index of the sequence. 

2832 :param increment: the increment value of the sequence. 

2833 :param minvalue: the minimum value of the sequence. 

2834 :param maxvalue: the maximum value of the sequence. 

2835 :param nominvalue: no minimum value of the sequence. 

2836 :param nomaxvalue: no maximum value of the sequence. 

2837 :param cycle: allows the sequence to wrap around when the maxvalue 

2838 or minvalue has been reached. 

2839 :param cache: optional integer value; number of future values in the 

2840 sequence which are calculated in advance. 

2841 :param order: optional boolean value; if ``True``, renders the 

2842 ORDER keyword. 

2843 

2844 """ 

2845 self.start = start 

2846 self.increment = increment 

2847 self.minvalue = minvalue 

2848 self.maxvalue = maxvalue 

2849 self.nominvalue = nominvalue 

2850 self.nomaxvalue = nomaxvalue 

2851 self.cycle = cycle 

2852 self.cache = cache 

2853 self.order = order 

2854 

2855 

2856class Sequence(IdentityOptions, DefaultGenerator): 

2857 """Represents a named database sequence. 

2858 

2859 The :class:`.Sequence` object represents the name and configurational 

2860 parameters of a database sequence. It also represents 

2861 a construct that can be "executed" by a SQLAlchemy :class:`_engine.Engine` 

2862 or :class:`_engine.Connection`, 

2863 rendering the appropriate "next value" function 

2864 for the target database and returning a result. 

2865 

2866 The :class:`.Sequence` is typically associated with a primary key column:: 

2867 

2868 some_table = Table( 

2869 'some_table', metadata, 

2870 Column('id', Integer, Sequence('some_table_seq'), 

2871 primary_key=True) 

2872 ) 

2873 

2874 When CREATE TABLE is emitted for the above :class:`_schema.Table`, if the 

2875 target platform supports sequences, a CREATE SEQUENCE statement will 

2876 be emitted as well. For platforms that don't support sequences, 

2877 the :class:`.Sequence` construct is ignored. 

2878 

2879 .. seealso:: 

2880 

2881 :ref:`defaults_sequences` 

2882 

2883 :class:`.CreateSequence` 

2884 

2885 :class:`.DropSequence` 

2886 

2887 """ 

2888 

2889 __visit_name__ = "sequence" 

2890 

2891 is_sequence = True 

2892 

2893 def __init__( 

2894 self, 

2895 name, 

2896 start=None, 

2897 increment=None, 

2898 minvalue=None, 

2899 maxvalue=None, 

2900 nominvalue=None, 

2901 nomaxvalue=None, 

2902 cycle=None, 

2903 schema=None, 

2904 cache=None, 

2905 order=None, 

2906 data_type=None, 

2907 optional=False, 

2908 quote=None, 

2909 metadata=None, 

2910 quote_schema=None, 

2911 for_update=False, 

2912 ): 

2913 """Construct a :class:`.Sequence` object. 

2914 

2915 :param name: the name of the sequence. 

2916 

2917 :param start: the starting index of the sequence. This value is 

2918 used when the CREATE SEQUENCE command is emitted to the database 

2919 as the value of the "START WITH" clause. If ``None``, the 

2920 clause is omitted, which on most platforms indicates a starting 

2921 value of 1. 

2922 :param increment: the increment value of the sequence. This 

2923 value is used when the CREATE SEQUENCE command is emitted to 

2924 the database as the value of the "INCREMENT BY" clause. If ``None``, 

2925 the clause is omitted, which on most platforms indicates an 

2926 increment of 1. 

2927 :param minvalue: the minimum value of the sequence. This 

2928 value is used when the CREATE SEQUENCE command is emitted to 

2929 the database as the value of the "MINVALUE" clause. If ``None``, 

2930 the clause is omitted, which on most platforms indicates a 

2931 minvalue of 1 and -2^63-1 for ascending and descending sequences, 

2932 respectively. 

2933 

2934 .. versionadded:: 1.0.7 

2935 

2936 :param maxvalue: the maximum value of the sequence. This 

2937 value is used when the CREATE SEQUENCE command is emitted to 

2938 the database as the value of the "MAXVALUE" clause. If ``None``, 

2939 the clause is omitted, which on most platforms indicates a 

2940 maxvalue of 2^63-1 and -1 for ascending and descending sequences, 

2941 respectively. 

2942 

2943 .. versionadded:: 1.0.7 

2944 

2945 :param nominvalue: no minimum value of the sequence. This 

2946 value is used when the CREATE SEQUENCE command is emitted to 

2947 the database as the value of the "NO MINVALUE" clause. If ``None``, 

2948 the clause is omitted, which on most platforms indicates a 

2949 minvalue of 1 and -2^63-1 for ascending and descending sequences, 

2950 respectively. 

2951 

2952 .. versionadded:: 1.0.7 

2953 

2954 :param nomaxvalue: no maximum value of the sequence. This 

2955 value is used when the CREATE SEQUENCE command is emitted to 

2956 the database as the value of the "NO MAXVALUE" clause. If ``None``, 

2957 the clause is omitted, which on most platforms indicates a 

2958 maxvalue of 2^63-1 and -1 for ascending and descending sequences, 

2959 respectively. 

2960 

2961 .. versionadded:: 1.0.7 

2962 

2963 :param cycle: allows the sequence to wrap around when the maxvalue 

2964 or minvalue has been reached by an ascending or descending sequence 

2965 respectively. This value is used when the CREATE SEQUENCE command 

2966 is emitted to the database as the "CYCLE" clause. If the limit is 

2967 reached, the next number generated will be the minvalue or maxvalue, 

2968 respectively. If cycle=False (the default) any calls to nextval 

2969 after the sequence has reached its maximum value will return an 

2970 error. 

2971 

2972 .. versionadded:: 1.0.7 

2973 

2974 :param schema: optional schema name for the sequence, if located 

2975 in a schema other than the default. The rules for selecting the 

2976 schema name when a :class:`_schema.MetaData` 

2977 is also present are the same 

2978 as that of :paramref:`_schema.Table.schema`. 

2979 

2980 :param cache: optional integer value; number of future values in the 

2981 sequence which are calculated in advance. Renders the CACHE keyword 

2982 understood by Oracle and PostgreSQL. 

2983 

2984 .. versionadded:: 1.1.12 

2985 

2986 :param order: optional boolean value; if ``True``, renders the 

2987 ORDER keyword, understood by Oracle, indicating the sequence is 

2988 definitively ordered. May be necessary to provide deterministic 

2989 ordering using Oracle RAC. 

2990 

2991 .. versionadded:: 1.1.12 

2992 

2993 :param data_type: The type to be returned by the sequence, for 

2994 dialects that allow us to choose between INTEGER, BIGINT, etc. 

2995 (e.g., mssql). 

2996 

2997 .. versionadded:: 1.4.0 

2998 

2999 :param optional: boolean value, when ``True``, indicates that this 

3000 :class:`.Sequence` object only needs to be explicitly generated 

3001 on backends that don't provide another way to generate primary 

3002 key identifiers. Currently, it essentially means, "don't create 

3003 this sequence on the PostgreSQL backend, where the SERIAL keyword 

3004 creates a sequence for us automatically". 

3005 :param quote: boolean value, when ``True`` or ``False``, explicitly 

3006 forces quoting of the :paramref:`_schema.Sequence.name` on or off. 

3007 When left at its default of ``None``, normal quoting rules based 

3008 on casing and reserved words take place. 

3009 :param quote_schema: Set the quoting preferences for the ``schema`` 

3010 name. 

3011 

3012 :param metadata: optional :class:`_schema.MetaData` object which this 

3013 :class:`.Sequence` will be associated with. A :class:`.Sequence` 

3014 that is associated with a :class:`_schema.MetaData` 

3015 gains the following 

3016 capabilities: 

3017 

3018 * The :class:`.Sequence` will inherit the 

3019 :paramref:`_schema.MetaData.schema` 

3020 parameter specified to the target :class:`_schema.MetaData`, which 

3021 affects the production of CREATE / DROP DDL, if any. 

3022 

3023 * The :meth:`.Sequence.create` and :meth:`.Sequence.drop` methods 

3024 automatically use the engine bound to the :class:`_schema.MetaData` 

3025 object, if any. 

3026 

3027 * The :meth:`_schema.MetaData.create_all` and 

3028 :meth:`_schema.MetaData.drop_all` 

3029 methods will emit CREATE / DROP for this :class:`.Sequence`, 

3030 even if the :class:`.Sequence` is not associated with any 

3031 :class:`_schema.Table` / :class:`_schema.Column` 

3032 that's a member of this 

3033 :class:`_schema.MetaData`. 

3034 

3035 The above behaviors can only occur if the :class:`.Sequence` is 

3036 explicitly associated with the :class:`_schema.MetaData` 

3037 via this parameter. 

3038 

3039 .. seealso:: 

3040 

3041 :ref:`sequence_metadata` - full discussion of the 

3042 :paramref:`.Sequence.metadata` parameter. 

3043 

3044 :param for_update: Indicates this :class:`.Sequence`, when associated 

3045 with a :class:`_schema.Column`, 

3046 should be invoked for UPDATE statements 

3047 on that column's table, rather than for INSERT statements, when 

3048 no value is otherwise present for that column in the statement. 

3049 

3050 """ 

3051 DefaultGenerator.__init__(self, for_update=for_update) 

3052 IdentityOptions.__init__( 

3053 self, 

3054 start=start, 

3055 increment=increment, 

3056 minvalue=minvalue, 

3057 maxvalue=maxvalue, 

3058 nominvalue=nominvalue, 

3059 nomaxvalue=nomaxvalue, 

3060 cycle=cycle, 

3061 cache=cache, 

3062 order=order, 

3063 ) 

3064 self.name = quoted_name(name, quote) 

3065 self.optional = optional 

3066 if schema is BLANK_SCHEMA: 

3067 self.schema = schema = None 

3068 elif metadata is not None and schema is None and metadata.schema: 

3069 self.schema = schema = metadata.schema 

3070 else: 

3071 self.schema = quoted_name(schema, quote_schema) 

3072 self.metadata = metadata 

3073 self._key = _get_table_key(name, schema) 

3074 if metadata: 

3075 self._set_metadata(metadata) 

3076 if data_type is not None: 

3077 self.data_type = to_instance(data_type) 

3078 else: 

3079 self.data_type = None 

3080 

3081 @util.memoized_property 

3082 def is_callable(self): 

3083 return False 

3084 

3085 @util.memoized_property 

3086 def is_clause_element(self): 

3087 return False 

3088 

3089 @util.preload_module("sqlalchemy.sql.functions") 

3090 def next_value(self): 

3091 """Return a :class:`.next_value` function element 

3092 which will render the appropriate increment function 

3093 for this :class:`.Sequence` within any SQL expression. 

3094 

3095 """ 

3096 if self.bind: 

3097 return util.preloaded.sql_functions.func.next_value( 

3098 self, bind=self.bind 

3099 ) 

3100 else: 

3101 return util.preloaded.sql_functions.func.next_value(self) 

3102 

3103 def _set_parent(self, column, **kw): 

3104 super(Sequence, self)._set_parent(column) 

3105 column._on_table_attach(self._set_table) 

3106 

3107 def _set_table(self, column, table): 

3108 self._set_metadata(table.metadata) 

3109 

3110 def _set_metadata(self, metadata): 

3111 self.metadata = metadata 

3112 self.metadata._sequences[self._key] = self 

3113 

3114 @property 

3115 def bind(self): 

3116 if self.metadata: 

3117 return self.metadata.bind 

3118 else: 

3119 return None 

3120 

3121 def create(self, bind=None, checkfirst=True): 

3122 """Creates this sequence in the database. 

3123 

3124 .. note:: the "bind" argument will be required in 

3125 SQLAlchemy 2.0. 

3126 

3127 """ 

3128 

3129 if bind is None: 

3130 bind = _bind_or_error(self) 

3131 bind._run_ddl_visitor(ddl.SchemaGenerator, self, checkfirst=checkfirst) 

3132 

3133 def drop(self, bind=None, checkfirst=True): 

3134 """Drops this sequence from the database. 

3135 

3136 .. note:: the "bind" argument will be required in 

3137 SQLAlchemy 2.0. 

3138 

3139 """ 

3140 

3141 if bind is None: 

3142 bind = _bind_or_error(self) 

3143 bind._run_ddl_visitor(ddl.SchemaDropper, self, checkfirst=checkfirst) 

3144 

3145 def _not_a_column_expr(self): 

3146 raise exc.InvalidRequestError( 

3147 "This %s cannot be used directly " 

3148 "as a column expression. Use func.next_value(sequence) " 

3149 "to produce a 'next value' function that's usable " 

3150 "as a column element." % self.__class__.__name__ 

3151 ) 

3152 

3153 

3154@inspection._self_inspects 

3155class FetchedValue(SchemaEventTarget): 

3156 """A marker for a transparent database-side default. 

3157 

3158 Use :class:`.FetchedValue` when the database is configured 

3159 to provide some automatic default for a column. 

3160 

3161 E.g.:: 

3162 

3163 Column('foo', Integer, FetchedValue()) 

3164 

3165 Would indicate that some trigger or default generator 

3166 will create a new value for the ``foo`` column during an 

3167 INSERT. 

3168 

3169 .. seealso:: 

3170 

3171 :ref:`triggered_columns` 

3172 

3173 """ 

3174 

3175 is_server_default = True 

3176 reflected = False 

3177 has_argument = False 

3178 is_clause_element = False 

3179 

3180 def __init__(self, for_update=False): 

3181 self.for_update = for_update 

3182 

3183 def _as_for_update(self, for_update): 

3184 if for_update == self.for_update: 

3185 return self 

3186 else: 

3187 return self._clone(for_update) 

3188 

3189 def _clone(self, for_update): 

3190 n = self.__class__.__new__(self.__class__) 

3191 n.__dict__.update(self.__dict__) 

3192 n.__dict__.pop("column", None) 

3193 n.for_update = for_update 

3194 return n 

3195 

3196 def _set_parent(self, column, **kw): 

3197 self.column = column 

3198 if self.for_update: 

3199 self.column.server_onupdate = self 

3200 else: 

3201 self.column.server_default = self 

3202 

3203 def __repr__(self): 

3204 return util.generic_repr(self) 

3205 

3206 

3207class DefaultClause(FetchedValue): 

3208 """A DDL-specified DEFAULT column value. 

3209 

3210 :class:`.DefaultClause` is a :class:`.FetchedValue` 

3211 that also generates a "DEFAULT" clause when 

3212 "CREATE TABLE" is emitted. 

3213 

3214 :class:`.DefaultClause` is generated automatically 

3215 whenever the ``server_default``, ``server_onupdate`` arguments of 

3216 :class:`_schema.Column` are used. A :class:`.DefaultClause` 

3217 can be passed positionally as well. 

3218 

3219 For example, the following:: 

3220 

3221 Column('foo', Integer, server_default="50") 

3222 

3223 Is equivalent to:: 

3224 

3225 Column('foo', Integer, DefaultClause("50")) 

3226 

3227 """ 

3228 

3229 has_argument = True 

3230 

3231 def __init__(self, arg, for_update=False, _reflected=False): 

3232 util.assert_arg_type( 

3233 arg, (util.string_types[0], ClauseElement, TextClause), "arg" 

3234 ) 

3235 super(DefaultClause, self).__init__(for_update) 

3236 self.arg = arg 

3237 self.reflected = _reflected 

3238 

3239 def __repr__(self): 

3240 return "DefaultClause(%r, for_update=%r)" % (self.arg, self.for_update) 

3241 

3242 

3243class Constraint(DialectKWArgs, SchemaItem): 

3244 """A table-level SQL constraint. 

3245 

3246 :class:`_schema.Constraint` serves as the base class for the series of 

3247 constraint objects that can be associated with :class:`_schema.Table` 

3248 objects, including :class:`_schema.PrimaryKeyConstraint`, 

3249 :class:`_schema.ForeignKeyConstraint` 

3250 :class:`_schema.UniqueConstraint`, and 

3251 :class:`_schema.CheckConstraint`. 

3252 

3253 """ 

3254 

3255 __visit_name__ = "constraint" 

3256 

3257 def __init__( 

3258 self, 

3259 name=None, 

3260 deferrable=None, 

3261 initially=None, 

3262 _create_rule=None, 

3263 info=None, 

3264 _type_bound=False, 

3265 **dialect_kw 

3266 ): 

3267 r"""Create a SQL constraint. 

3268 

3269 :param name: 

3270 Optional, the in-database name of this ``Constraint``. 

3271 

3272 :param deferrable: 

3273 Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when 

3274 issuing DDL for this constraint. 

3275 

3276 :param initially: 

3277 Optional string. If set, emit INITIALLY <value> when issuing DDL 

3278 for this constraint. 

3279 

3280 :param info: Optional data dictionary which will be populated into the 

3281 :attr:`.SchemaItem.info` attribute of this object. 

3282 

3283 .. versionadded:: 1.0.0 

3284 

3285 :param \**dialect_kw: Additional keyword arguments are dialect 

3286 specific, and passed in the form ``<dialectname>_<argname>``. See 

3287 the documentation regarding an individual dialect at 

3288 :ref:`dialect_toplevel` for detail on documented arguments. 

3289 

3290 :param _create_rule: 

3291 used internally by some datatypes that also create constraints. 

3292 

3293 :param _type_bound: 

3294 used internally to indicate that this constraint is associated with 

3295 a specific datatype. 

3296 

3297 """ 

3298 

3299 self.name = name 

3300 self.deferrable = deferrable 

3301 self.initially = initially 

3302 if info: 

3303 self.info = info 

3304 self._create_rule = _create_rule 

3305 self._type_bound = _type_bound 

3306 util.set_creation_order(self) 

3307 self._validate_dialect_kwargs(dialect_kw) 

3308 

3309 @property 

3310 def table(self): 

3311 try: 

3312 if isinstance(self.parent, Table): 

3313 return self.parent 

3314 except AttributeError: 

3315 pass 

3316 raise exc.InvalidRequestError( 

3317 "This constraint is not bound to a table. Did you " 

3318 "mean to call table.append_constraint(constraint) ?" 

3319 ) 

3320 

3321 def _set_parent(self, parent, **kw): 

3322 self.parent = parent 

3323 parent.constraints.add(self) 

3324 

3325 @util.deprecated( 

3326 "1.4", 

3327 "The :meth:`_schema.Constraint.copy` method is deprecated " 

3328 "and will be removed in a future release.", 

3329 ) 

3330 def copy(self, **kw): 

3331 return self._copy(**kw) 

3332 

3333 def _copy(self, **kw): 

3334 raise NotImplementedError() 

3335 

3336 

3337class ColumnCollectionMixin(object): 

3338 

3339 columns = None 

3340 """A :class:`_expression.ColumnCollection` of :class:`_schema.Column` 

3341 objects. 

3342 

3343 This collection represents the columns which are referred to by 

3344 this object. 

3345 

3346 """ 

3347 

3348 _allow_multiple_tables = False 

3349 

3350 def __init__(self, *columns, **kw): 

3351 _autoattach = kw.pop("_autoattach", True) 

3352 self._column_flag = kw.pop("_column_flag", False) 

3353 self.columns = DedupeColumnCollection() 

3354 

3355 processed_expressions = kw.pop("_gather_expressions", None) 

3356 if processed_expressions is not None: 

3357 self._pending_colargs = [] 

3358 for ( 

3359 expr, 

3360 column, 

3361 strname, 

3362 add_element, 

3363 ) in coercions.expect_col_expression_collection( 

3364 roles.DDLConstraintColumnRole, columns 

3365 ): 

3366 self._pending_colargs.append(add_element) 

3367 processed_expressions.append(expr) 

3368 else: 

3369 self._pending_colargs = [ 

3370 coercions.expect(roles.DDLConstraintColumnRole, column) 

3371 for column in columns 

3372 ] 

3373 

3374 if _autoattach and self._pending_colargs: 

3375 self._check_attach() 

3376 

3377 def _check_attach(self, evt=False): 

3378 col_objs = [c for c in self._pending_colargs if isinstance(c, Column)] 

3379 

3380 cols_w_table = [c for c in col_objs if isinstance(c.table, Table)] 

3381 

3382 cols_wo_table = set(col_objs).difference(cols_w_table) 

3383 if cols_wo_table: 

3384 # feature #3341 - place event listeners for Column objects 

3385 # such that when all those cols are attached, we autoattach. 

3386 assert not evt, "Should not reach here on event call" 

3387 

3388 # issue #3411 - don't do the per-column auto-attach if some of the 

3389 # columns are specified as strings. 

3390 has_string_cols = set( 

3391 c for c in self._pending_colargs if c is not None 

3392 ).difference(col_objs) 

3393 if not has_string_cols: 

3394 

3395 def _col_attached(column, table): 

3396 # this isinstance() corresponds with the 

3397 # isinstance() above; only want to count Table-bound 

3398 # columns 

3399 if isinstance(table, Table): 

3400 cols_wo_table.discard(column) 

3401 if not cols_wo_table: 

3402 self._check_attach(evt=True) 

3403 

3404 self._cols_wo_table = cols_wo_table 

3405 for col in cols_wo_table: 

3406 col._on_table_attach(_col_attached) 

3407 return 

3408 

3409 columns = cols_w_table 

3410 

3411 tables = {c.table for c in columns} 

3412 if len(tables) == 1: 

3413 self._set_parent_with_dispatch(tables.pop()) 

3414 elif len(tables) > 1 and not self._allow_multiple_tables: 

3415 table = columns[0].table 

3416 others = [c for c in columns[1:] if c.table is not table] 

3417 if others: 

3418 raise exc.ArgumentError( 

3419 "Column(s) %s are not part of table '%s'." 

3420 % ( 

3421 ", ".join("'%s'" % c for c in others), 

3422 table.description, 

3423 ) 

3424 ) 

3425 

3426 def _col_expressions(self, table): 

3427 return [ 

3428 table.c[col] if isinstance(col, util.string_types) else col 

3429 for col in self._pending_colargs 

3430 ] 

3431 

3432 def _set_parent(self, table, **kw): 

3433 for col in self._col_expressions(table): 

3434 if col is not None: 

3435 self.columns.add(col) 

3436 

3437 

3438class ColumnCollectionConstraint(ColumnCollectionMixin, Constraint): 

3439 """A constraint that proxies a ColumnCollection.""" 

3440 

3441 def __init__(self, *columns, **kw): 

3442 r""" 

3443 :param \*columns: 

3444 A sequence of column names or Column objects. 

3445 

3446 :param name: 

3447 Optional, the in-database name of this constraint. 

3448 

3449 :param deferrable: 

3450 Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when 

3451 issuing DDL for this constraint. 

3452 

3453 :param initially: 

3454 Optional string. If set, emit INITIALLY <value> when issuing DDL 

3455 for this constraint. 

3456 

3457 :param \**kw: other keyword arguments including dialect-specific 

3458 arguments are propagated to the :class:`.Constraint` superclass. 

3459 

3460 """ 

3461 _autoattach = kw.pop("_autoattach", True) 

3462 _column_flag = kw.pop("_column_flag", False) 

3463 Constraint.__init__(self, **kw) 

3464 ColumnCollectionMixin.__init__( 

3465 self, *columns, _autoattach=_autoattach, _column_flag=_column_flag 

3466 ) 

3467 

3468 columns = None 

3469 """A :class:`_expression.ColumnCollection` representing the set of columns 

3470 for this constraint. 

3471 

3472 """ 

3473 

3474 def _set_parent(self, table, **kw): 

3475 Constraint._set_parent(self, table) 

3476 ColumnCollectionMixin._set_parent(self, table) 

3477 

3478 def __contains__(self, x): 

3479 return x in self.columns 

3480 

3481 @util.deprecated( 

3482 "1.4", 

3483 "The :meth:`_schema.ColumnCollectionConstraint.copy` method " 

3484 "is deprecated and will be removed in a future release.", 

3485 ) 

3486 def copy(self, target_table=None, **kw): 

3487 return self._copy(target_table=target_table, **kw) 

3488 

3489 def _copy(self, target_table=None, **kw): 

3490 # ticket #5276 

3491 constraint_kwargs = {} 

3492 for dialect_name in self.dialect_options: 

3493 dialect_options = self.dialect_options[dialect_name]._non_defaults 

3494 for ( 

3495 dialect_option_key, 

3496 dialect_option_value, 

3497 ) in dialect_options.items(): 

3498 constraint_kwargs[ 

3499 dialect_name + "_" + dialect_option_key 

3500 ] = dialect_option_value 

3501 

3502 c = self.__class__( 

3503 name=self.name, 

3504 deferrable=self.deferrable, 

3505 initially=self.initially, 

3506 *[ 

3507 _copy_expression(expr, self.parent, target_table) 

3508 for expr in self.columns 

3509 ], 

3510 **constraint_kwargs 

3511 ) 

3512 return self._schema_item_copy(c) 

3513 

3514 def contains_column(self, col): 

3515 """Return True if this constraint contains the given column. 

3516 

3517 Note that this object also contains an attribute ``.columns`` 

3518 which is a :class:`_expression.ColumnCollection` of 

3519 :class:`_schema.Column` objects. 

3520 

3521 """ 

3522 

3523 return self.columns.contains_column(col) 

3524 

3525 def __iter__(self): 

3526 return iter(self.columns) 

3527 

3528 def __len__(self): 

3529 return len(self.columns) 

3530 

3531 

3532class CheckConstraint(ColumnCollectionConstraint): 

3533 """A table- or column-level CHECK constraint. 

3534 

3535 Can be included in the definition of a Table or Column. 

3536 """ 

3537 

3538 _allow_multiple_tables = True 

3539 

3540 __visit_name__ = "table_or_column_check_constraint" 

3541 

3542 @_document_text_coercion( 

3543 "sqltext", 

3544 ":class:`.CheckConstraint`", 

3545 ":paramref:`.CheckConstraint.sqltext`", 

3546 ) 

3547 def __init__( 

3548 self, 

3549 sqltext, 

3550 name=None, 

3551 deferrable=None, 

3552 initially=None, 

3553 table=None, 

3554 info=None, 

3555 _create_rule=None, 

3556 _autoattach=True, 

3557 _type_bound=False, 

3558 **kw 

3559 ): 

3560 r"""Construct a CHECK constraint. 

3561 

3562 :param sqltext: 

3563 A string containing the constraint definition, which will be used 

3564 verbatim, or a SQL expression construct. If given as a string, 

3565 the object is converted to a :func:`_expression.text` object. 

3566 If the textual 

3567 string includes a colon character, escape this using a backslash:: 

3568 

3569 CheckConstraint(r"foo ~ E'a(?\:b|c)d") 

3570 

3571 :param name: 

3572 Optional, the in-database name of the constraint. 

3573 

3574 :param deferrable: 

3575 Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when 

3576 issuing DDL for this constraint. 

3577 

3578 :param initially: 

3579 Optional string. If set, emit INITIALLY <value> when issuing DDL 

3580 for this constraint. 

3581 

3582 :param info: Optional data dictionary which will be populated into the 

3583 :attr:`.SchemaItem.info` attribute of this object. 

3584 

3585 .. versionadded:: 1.0.0 

3586 

3587 """ 

3588 

3589 self.sqltext = coercions.expect(roles.DDLExpressionRole, sqltext) 

3590 columns = [] 

3591 visitors.traverse(self.sqltext, {}, {"column": columns.append}) 

3592 

3593 super(CheckConstraint, self).__init__( 

3594 name=name, 

3595 deferrable=deferrable, 

3596 initially=initially, 

3597 _create_rule=_create_rule, 

3598 info=info, 

3599 _type_bound=_type_bound, 

3600 _autoattach=_autoattach, 

3601 *columns, 

3602 **kw 

3603 ) 

3604 if table is not None: 

3605 self._set_parent_with_dispatch(table) 

3606 

3607 @property 

3608 def is_column_level(self): 

3609 return not isinstance(self.parent, Table) 

3610 

3611 @util.deprecated( 

3612 "1.4", 

3613 "The :meth:`_schema.CheckConstraint.copy` method is deprecated " 

3614 "and will be removed in a future release.", 

3615 ) 

3616 def copy(self, target_table=None, **kw): 

3617 return self._copy(target_table=target_table, **kw) 

3618 

3619 def _copy(self, target_table=None, **kw): 

3620 if target_table is not None: 

3621 # note that target_table is None for the copy process of 

3622 # a column-bound CheckConstraint, so this path is not reached 

3623 # in that case. 

3624 sqltext = _copy_expression(self.sqltext, self.table, target_table) 

3625 else: 

3626 sqltext = self.sqltext 

3627 c = CheckConstraint( 

3628 sqltext, 

3629 name=self.name, 

3630 initially=self.initially, 

3631 deferrable=self.deferrable, 

3632 _create_rule=self._create_rule, 

3633 table=target_table, 

3634 _autoattach=False, 

3635 _type_bound=self._type_bound, 

3636 ) 

3637 return self._schema_item_copy(c) 

3638 

3639 

3640class ForeignKeyConstraint(ColumnCollectionConstraint): 

3641 """A table-level FOREIGN KEY constraint. 

3642 

3643 Defines a single column or composite FOREIGN KEY ... REFERENCES 

3644 constraint. For a no-frills, single column foreign key, adding a 

3645 :class:`_schema.ForeignKey` to the definition of a :class:`_schema.Column` 

3646 is a 

3647 shorthand equivalent for an unnamed, single column 

3648 :class:`_schema.ForeignKeyConstraint`. 

3649 

3650 Examples of foreign key configuration are in :ref:`metadata_foreignkeys`. 

3651 

3652 """ 

3653 

3654 __visit_name__ = "foreign_key_constraint" 

3655 

3656 def __init__( 

3657 self, 

3658 columns, 

3659 refcolumns, 

3660 name=None, 

3661 onupdate=None, 

3662 ondelete=None, 

3663 deferrable=None, 

3664 initially=None, 

3665 use_alter=False, 

3666 link_to_name=False, 

3667 match=None, 

3668 table=None, 

3669 info=None, 

3670 **dialect_kw 

3671 ): 

3672 r"""Construct a composite-capable FOREIGN KEY. 

3673 

3674 :param columns: A sequence of local column names. The named columns 

3675 must be defined and present in the parent Table. The names should 

3676 match the ``key`` given to each column (defaults to the name) unless 

3677 ``link_to_name`` is True. 

3678 

3679 :param refcolumns: A sequence of foreign column names or Column 

3680 objects. The columns must all be located within the same Table. 

3681 

3682 :param name: Optional, the in-database name of the key. 

3683 

3684 :param onupdate: Optional string. If set, emit ON UPDATE <value> when 

3685 issuing DDL for this constraint. Typical values include CASCADE, 

3686 DELETE and RESTRICT. 

3687 

3688 :param ondelete: Optional string. If set, emit ON DELETE <value> when 

3689 issuing DDL for this constraint. Typical values include CASCADE, 

3690 DELETE and RESTRICT. 

3691 

3692 :param deferrable: Optional bool. If set, emit DEFERRABLE or NOT 

3693 DEFERRABLE when issuing DDL for this constraint. 

3694 

3695 :param initially: Optional string. If set, emit INITIALLY <value> when 

3696 issuing DDL for this constraint. 

3697 

3698 :param link_to_name: if True, the string name given in ``column`` is 

3699 the rendered name of the referenced column, not its locally assigned 

3700 ``key``. 

3701 

3702 :param use_alter: If True, do not emit the DDL for this constraint as 

3703 part of the CREATE TABLE definition. Instead, generate it via an 

3704 ALTER TABLE statement issued after the full collection of tables 

3705 have been created, and drop it via an ALTER TABLE statement before 

3706 the full collection of tables are dropped. 

3707 

3708 The use of :paramref:`_schema.ForeignKeyConstraint.use_alter` is 

3709 particularly geared towards the case where two or more tables 

3710 are established within a mutually-dependent foreign key constraint 

3711 relationship; however, the :meth:`_schema.MetaData.create_all` and 

3712 :meth:`_schema.MetaData.drop_all` 

3713 methods will perform this resolution 

3714 automatically, so the flag is normally not needed. 

3715 

3716 .. versionchanged:: 1.0.0 Automatic resolution of foreign key 

3717 cycles has been added, removing the need to use the 

3718 :paramref:`_schema.ForeignKeyConstraint.use_alter` in typical use 

3719 cases. 

3720 

3721 .. seealso:: 

3722 

3723 :ref:`use_alter` 

3724 

3725 :param match: Optional string. If set, emit MATCH <value> when issuing 

3726 DDL for this constraint. Typical values include SIMPLE, PARTIAL 

3727 and FULL. 

3728 

3729 :param info: Optional data dictionary which will be populated into the 

3730 :attr:`.SchemaItem.info` attribute of this object. 

3731 

3732 .. versionadded:: 1.0.0 

3733 

3734 :param \**dialect_kw: Additional keyword arguments are dialect 

3735 specific, and passed in the form ``<dialectname>_<argname>``. See 

3736 the documentation regarding an individual dialect at 

3737 :ref:`dialect_toplevel` for detail on documented arguments. 

3738 

3739 .. versionadded:: 0.9.2 

3740 

3741 """ 

3742 

3743 Constraint.__init__( 

3744 self, 

3745 name=name, 

3746 deferrable=deferrable, 

3747 initially=initially, 

3748 info=info, 

3749 **dialect_kw 

3750 ) 

3751 self.onupdate = onupdate 

3752 self.ondelete = ondelete 

3753 self.link_to_name = link_to_name 

3754 self.use_alter = use_alter 

3755 self.match = match 

3756 

3757 if len(set(columns)) != len(refcolumns): 

3758 if len(set(columns)) != len(columns): 

3759 # e.g. FOREIGN KEY (a, a) REFERENCES r (b, c) 

3760 raise exc.ArgumentError( 

3761 "ForeignKeyConstraint with duplicate source column " 

3762 "references are not supported." 

3763 ) 

3764 else: 

3765 # e.g. FOREIGN KEY (a) REFERENCES r (b, c) 

3766 # paraphrasing 

3767 # https://www.postgresql.org/docs/current/static/ddl-constraints.html 

3768 raise exc.ArgumentError( 

3769 "ForeignKeyConstraint number " 

3770 "of constrained columns must match the number of " 

3771 "referenced columns." 

3772 ) 

3773 

3774 # standalone ForeignKeyConstraint - create 

3775 # associated ForeignKey objects which will be applied to hosted 

3776 # Column objects (in col.foreign_keys), either now or when attached 

3777 # to the Table for string-specified names 

3778 self.elements = [ 

3779 ForeignKey( 

3780 refcol, 

3781 _constraint=self, 

3782 name=self.name, 

3783 onupdate=self.onupdate, 

3784 ondelete=self.ondelete, 

3785 use_alter=self.use_alter, 

3786 link_to_name=self.link_to_name, 

3787 match=self.match, 

3788 deferrable=self.deferrable, 

3789 initially=self.initially, 

3790 **self.dialect_kwargs 

3791 ) 

3792 for refcol in refcolumns 

3793 ] 

3794 

3795 ColumnCollectionMixin.__init__(self, *columns) 

3796 if table is not None: 

3797 if hasattr(self, "parent"): 

3798 assert table is self.parent 

3799 self._set_parent_with_dispatch(table) 

3800 

3801 def _append_element(self, column, fk): 

3802 self.columns.add(column) 

3803 self.elements.append(fk) 

3804 

3805 columns = None 

3806 """A :class:`_expression.ColumnCollection` representing the set of columns 

3807 for this constraint. 

3808 

3809 """ 

3810 

3811 elements = None 

3812 """A sequence of :class:`_schema.ForeignKey` objects. 

3813 

3814 Each :class:`_schema.ForeignKey` 

3815 represents a single referring column/referred 

3816 column pair. 

3817 

3818 This collection is intended to be read-only. 

3819 

3820 """ 

3821 

3822 @property 

3823 def _elements(self): 

3824 # legacy - provide a dictionary view of (column_key, fk) 

3825 return util.OrderedDict(zip(self.column_keys, self.elements)) 

3826 

3827 @property 

3828 def _referred_schema(self): 

3829 for elem in self.elements: 

3830 return elem._referred_schema 

3831 else: 

3832 return None 

3833 

3834 @property 

3835 def referred_table(self): 

3836 """The :class:`_schema.Table` object to which this 

3837 :class:`_schema.ForeignKeyConstraint` references. 

3838 

3839 This is a dynamically calculated attribute which may not be available 

3840 if the constraint and/or parent table is not yet associated with 

3841 a metadata collection that contains the referred table. 

3842 

3843 .. versionadded:: 1.0.0 

3844 

3845 """ 

3846 return self.elements[0].column.table 

3847 

3848 def _validate_dest_table(self, table): 

3849 table_keys = set([elem._table_key() for elem in self.elements]) 

3850 if None not in table_keys and len(table_keys) > 1: 

3851 elem0, elem1 = sorted(table_keys)[0:2] 

3852 raise exc.ArgumentError( 

3853 "ForeignKeyConstraint on %s(%s) refers to " 

3854 "multiple remote tables: %s and %s" 

3855 % (table.fullname, self._col_description, elem0, elem1) 

3856 ) 

3857 

3858 @property 

3859 def column_keys(self): 

3860 """Return a list of string keys representing the local 

3861 columns in this :class:`_schema.ForeignKeyConstraint`. 

3862 

3863 This list is either the original string arguments sent 

3864 to the constructor of the :class:`_schema.ForeignKeyConstraint`, 

3865 or if the constraint has been initialized with :class:`_schema.Column` 

3866 objects, is the string ``.key`` of each element. 

3867 

3868 .. versionadded:: 1.0.0 

3869 

3870 """ 

3871 if hasattr(self, "parent"): 

3872 return self.columns.keys() 

3873 else: 

3874 return [ 

3875 col.key if isinstance(col, ColumnElement) else str(col) 

3876 for col in self._pending_colargs 

3877 ] 

3878 

3879 @property 

3880 def _col_description(self): 

3881 return ", ".join(self.column_keys) 

3882 

3883 def _set_parent(self, table, **kw): 

3884 Constraint._set_parent(self, table) 

3885 

3886 try: 

3887 ColumnCollectionConstraint._set_parent(self, table) 

3888 except KeyError as ke: 

3889 util.raise_( 

3890 exc.ArgumentError( 

3891 "Can't create ForeignKeyConstraint " 

3892 "on table '%s': no column " 

3893 "named '%s' is present." % (table.description, ke.args[0]) 

3894 ), 

3895 from_=ke, 

3896 ) 

3897 

3898 for col, fk in zip(self.columns, self.elements): 

3899 if not hasattr(fk, "parent") or fk.parent is not col: 

3900 fk._set_parent_with_dispatch(col) 

3901 

3902 self._validate_dest_table(table) 

3903 

3904 @util.deprecated( 

3905 "1.4", 

3906 "The :meth:`_schema.ForeignKeyConstraint.copy` method is deprecated " 

3907 "and will be removed in a future release.", 

3908 ) 

3909 def copy(self, schema=None, target_table=None, **kw): 

3910 return self._copy(schema=schema, target_table=target_table, **kw) 

3911 

3912 def _copy(self, schema=None, target_table=None, **kw): 

3913 fkc = ForeignKeyConstraint( 

3914 [x.parent.key for x in self.elements], 

3915 [ 

3916 x._get_colspec( 

3917 schema=schema, 

3918 table_name=target_table.name 

3919 if target_table is not None 

3920 and x._table_key() == x.parent.table.key 

3921 else None, 

3922 ) 

3923 for x in self.elements 

3924 ], 

3925 name=self.name, 

3926 onupdate=self.onupdate, 

3927 ondelete=self.ondelete, 

3928 use_alter=self.use_alter, 

3929 deferrable=self.deferrable, 

3930 initially=self.initially, 

3931 link_to_name=self.link_to_name, 

3932 match=self.match, 

3933 ) 

3934 for self_fk, other_fk in zip(self.elements, fkc.elements): 

3935 self_fk._schema_item_copy(other_fk) 

3936 return self._schema_item_copy(fkc) 

3937 

3938 

3939class PrimaryKeyConstraint(ColumnCollectionConstraint): 

3940 """A table-level PRIMARY KEY constraint. 

3941 

3942 The :class:`.PrimaryKeyConstraint` object is present automatically 

3943 on any :class:`_schema.Table` object; it is assigned a set of 

3944 :class:`_schema.Column` objects corresponding to those marked with 

3945 the :paramref:`_schema.Column.primary_key` flag:: 

3946 

3947 >>> my_table = Table('mytable', metadata, 

3948 ... Column('id', Integer, primary_key=True), 

3949 ... Column('version_id', Integer, primary_key=True), 

3950 ... Column('data', String(50)) 

3951 ... ) 

3952 >>> my_table.primary_key 

3953 PrimaryKeyConstraint( 

3954 Column('id', Integer(), table=<mytable>, 

3955 primary_key=True, nullable=False), 

3956 Column('version_id', Integer(), table=<mytable>, 

3957 primary_key=True, nullable=False) 

3958 ) 

3959 

3960 The primary key of a :class:`_schema.Table` can also be specified by using 

3961 a :class:`.PrimaryKeyConstraint` object explicitly; in this mode of usage, 

3962 the "name" of the constraint can also be specified, as well as other 

3963 options which may be recognized by dialects:: 

3964 

3965 my_table = Table('mytable', metadata, 

3966 Column('id', Integer), 

3967 Column('version_id', Integer), 

3968 Column('data', String(50)), 

3969 PrimaryKeyConstraint('id', 'version_id', 

3970 name='mytable_pk') 

3971 ) 

3972 

3973 The two styles of column-specification should generally not be mixed. 

3974 An warning is emitted if the columns present in the 

3975 :class:`.PrimaryKeyConstraint` 

3976 don't match the columns that were marked as ``primary_key=True``, if both 

3977 are present; in this case, the columns are taken strictly from the 

3978 :class:`.PrimaryKeyConstraint` declaration, and those columns otherwise 

3979 marked as ``primary_key=True`` are ignored. This behavior is intended to 

3980 be backwards compatible with previous behavior. 

3981 

3982 .. versionchanged:: 0.9.2 Using a mixture of columns within a 

3983 :class:`.PrimaryKeyConstraint` in addition to columns marked as 

3984 ``primary_key=True`` now emits a warning if the lists don't match. 

3985 The ultimate behavior of ignoring those columns marked with the flag 

3986 only is currently maintained for backwards compatibility; this warning 

3987 may raise an exception in a future release. 

3988 

3989 For the use case where specific options are to be specified on the 

3990 :class:`.PrimaryKeyConstraint`, but the usual style of using 

3991 ``primary_key=True`` flags is still desirable, an empty 

3992 :class:`.PrimaryKeyConstraint` may be specified, which will take on the 

3993 primary key column collection from the :class:`_schema.Table` based on the 

3994 flags:: 

3995 

3996 my_table = Table('mytable', metadata, 

3997 Column('id', Integer, primary_key=True), 

3998 Column('version_id', Integer, primary_key=True), 

3999 Column('data', String(50)), 

4000 PrimaryKeyConstraint(name='mytable_pk', 

4001 mssql_clustered=True) 

4002 ) 

4003 

4004 .. versionadded:: 0.9.2 an empty :class:`.PrimaryKeyConstraint` may now 

4005 be specified for the purposes of establishing keyword arguments with 

4006 the constraint, independently of the specification of "primary key" 

4007 columns within the :class:`_schema.Table` itself; columns marked as 

4008 ``primary_key=True`` will be gathered into the empty constraint's 

4009 column collection. 

4010 

4011 """ 

4012 

4013 __visit_name__ = "primary_key_constraint" 

4014 

4015 def __init__(self, *columns, **kw): 

4016 self._implicit_generated = kw.pop("_implicit_generated", False) 

4017 super(PrimaryKeyConstraint, self).__init__(*columns, **kw) 

4018 

4019 def _set_parent(self, table, **kw): 

4020 super(PrimaryKeyConstraint, self)._set_parent(table) 

4021 

4022 if table.primary_key is not self: 

4023 table.constraints.discard(table.primary_key) 

4024 table.primary_key = self 

4025 table.constraints.add(self) 

4026 

4027 table_pks = [c for c in table.c if c.primary_key] 

4028 if self.columns and table_pks and set(table_pks) != set(self.columns): 

4029 util.warn( 

4030 "Table '%s' specifies columns %s as primary_key=True, " 

4031 "not matching locally specified columns %s; setting the " 

4032 "current primary key columns to %s. This warning " 

4033 "may become an exception in a future release" 

4034 % ( 

4035 table.name, 

4036 ", ".join("'%s'" % c.name for c in table_pks), 

4037 ", ".join("'%s'" % c.name for c in self.columns), 

4038 ", ".join("'%s'" % c.name for c in self.columns), 

4039 ) 

4040 ) 

4041 table_pks[:] = [] 

4042 

4043 for c in self.columns: 

4044 c.primary_key = True 

4045 if c._user_defined_nullable is NULL_UNSPECIFIED: 

4046 c.nullable = False 

4047 if table_pks: 

4048 self.columns.extend(table_pks) 

4049 

4050 def _reload(self, columns): 

4051 """repopulate this :class:`.PrimaryKeyConstraint` given 

4052 a set of columns. 

4053 

4054 Existing columns in the table that are marked as primary_key=True 

4055 are maintained. 

4056 

4057 Also fires a new event. 

4058 

4059 This is basically like putting a whole new 

4060 :class:`.PrimaryKeyConstraint` object on the parent 

4061 :class:`_schema.Table` object without actually replacing the object. 

4062 

4063 The ordering of the given list of columns is also maintained; these 

4064 columns will be appended to the list of columns after any which 

4065 are already present. 

4066 

4067 """ 

4068 # set the primary key flag on new columns. 

4069 # note any existing PK cols on the table also have their 

4070 # flag still set. 

4071 for col in columns: 

4072 col.primary_key = True 

4073 

4074 self.columns.extend(columns) 

4075 

4076 PrimaryKeyConstraint._autoincrement_column._reset(self) 

4077 self._set_parent_with_dispatch(self.table) 

4078 

4079 def _replace(self, col): 

4080 PrimaryKeyConstraint._autoincrement_column._reset(self) 

4081 self.columns.replace(col) 

4082 

4083 self.dispatch._sa_event_column_added_to_pk_constraint(self, col) 

4084 

4085 @property 

4086 def columns_autoinc_first(self): 

4087 autoinc = self._autoincrement_column 

4088 

4089 if autoinc is not None: 

4090 return [autoinc] + [c for c in self.columns if c is not autoinc] 

4091 else: 

4092 return list(self.columns) 

4093 

4094 @util.memoized_property 

4095 def _autoincrement_column(self): 

4096 def _validate_autoinc(col, autoinc_true): 

4097 if col.type._type_affinity is None or not issubclass( 

4098 col.type._type_affinity, 

4099 ( 

4100 type_api.INTEGERTYPE._type_affinity, 

4101 type_api.NUMERICTYPE._type_affinity, 

4102 ), 

4103 ): 

4104 if autoinc_true: 

4105 raise exc.ArgumentError( 

4106 "Column type %s on column '%s' is not " 

4107 "compatible with autoincrement=True" % (col.type, col) 

4108 ) 

4109 else: 

4110 return False 

4111 elif ( 

4112 not isinstance(col.default, (type(None), Sequence)) 

4113 and not autoinc_true 

4114 ): 

4115 return False 

4116 elif ( 

4117 col.server_default is not None 

4118 and not isinstance(col.server_default, Identity) 

4119 and not autoinc_true 

4120 ): 

4121 return False 

4122 elif col.foreign_keys and col.autoincrement not in ( 

4123 True, 

4124 "ignore_fk", 

4125 ): 

4126 return False 

4127 return True 

4128 

4129 if len(self.columns) == 1: 

4130 col = list(self.columns)[0] 

4131 

4132 if col.autoincrement is True: 

4133 _validate_autoinc(col, True) 

4134 return col 

4135 elif ( 

4136 col.autoincrement 

4137 in ( 

4138 "auto", 

4139 "ignore_fk", 

4140 ) 

4141 and _validate_autoinc(col, False) 

4142 ): 

4143 return col 

4144 

4145 else: 

4146 autoinc = None 

4147 for col in self.columns: 

4148 if col.autoincrement is True: 

4149 _validate_autoinc(col, True) 

4150 if autoinc is not None: 

4151 raise exc.ArgumentError( 

4152 "Only one Column may be marked " 

4153 "autoincrement=True, found both %s and %s." 

4154 % (col.name, autoinc.name) 

4155 ) 

4156 else: 

4157 autoinc = col 

4158 

4159 return autoinc 

4160 

4161 

4162class UniqueConstraint(ColumnCollectionConstraint): 

4163 """A table-level UNIQUE constraint. 

4164 

4165 Defines a single column or composite UNIQUE constraint. For a no-frills, 

4166 single column constraint, adding ``unique=True`` to the ``Column`` 

4167 definition is a shorthand equivalent for an unnamed, single column 

4168 UniqueConstraint. 

4169 """ 

4170 

4171 __visit_name__ = "unique_constraint" 

4172 

4173 

4174class Index(DialectKWArgs, ColumnCollectionMixin, SchemaItem): 

4175 """A table-level INDEX. 

4176 

4177 Defines a composite (one or more column) INDEX. 

4178 

4179 E.g.:: 

4180 

4181 sometable = Table("sometable", metadata, 

4182 Column("name", String(50)), 

4183 Column("address", String(100)) 

4184 ) 

4185 

4186 Index("some_index", sometable.c.name) 

4187 

4188 For a no-frills, single column index, adding 

4189 :class:`_schema.Column` also supports ``index=True``:: 

4190 

4191 sometable = Table("sometable", metadata, 

4192 Column("name", String(50), index=True) 

4193 ) 

4194 

4195 For a composite index, multiple columns can be specified:: 

4196 

4197 Index("some_index", sometable.c.name, sometable.c.address) 

4198 

4199 Functional indexes are supported as well, typically by using the 

4200 :data:`.func` construct in conjunction with table-bound 

4201 :class:`_schema.Column` objects:: 

4202 

4203 Index("some_index", func.lower(sometable.c.name)) 

4204 

4205 An :class:`.Index` can also be manually associated with a 

4206 :class:`_schema.Table`, 

4207 either through inline declaration or using 

4208 :meth:`_schema.Table.append_constraint`. When this approach is used, 

4209 the names 

4210 of the indexed columns can be specified as strings:: 

4211 

4212 Table("sometable", metadata, 

4213 Column("name", String(50)), 

4214 Column("address", String(100)), 

4215 Index("some_index", "name", "address") 

4216 ) 

4217 

4218 To support functional or expression-based indexes in this form, the 

4219 :func:`_expression.text` construct may be used:: 

4220 

4221 from sqlalchemy import text 

4222 

4223 Table("sometable", metadata, 

4224 Column("name", String(50)), 

4225 Column("address", String(100)), 

4226 Index("some_index", text("lower(name)")) 

4227 ) 

4228 

4229 .. versionadded:: 0.9.5 the :func:`_expression.text` 

4230 construct may be used to 

4231 specify :class:`.Index` expressions, provided the :class:`.Index` 

4232 is explicitly associated with the :class:`_schema.Table`. 

4233 

4234 

4235 .. seealso:: 

4236 

4237 :ref:`schema_indexes` - General information on :class:`.Index`. 

4238 

4239 :ref:`postgresql_indexes` - PostgreSQL-specific options available for 

4240 the :class:`.Index` construct. 

4241 

4242 :ref:`mysql_indexes` - MySQL-specific options available for the 

4243 :class:`.Index` construct. 

4244 

4245 :ref:`mssql_indexes` - MSSQL-specific options available for the 

4246 :class:`.Index` construct. 

4247 

4248 """ 

4249 

4250 __visit_name__ = "index" 

4251 

4252 def __init__(self, name, *expressions, **kw): 

4253 r"""Construct an index object. 

4254 

4255 :param name: 

4256 The name of the index 

4257 

4258 :param \*expressions: 

4259 Column expressions to include in the index. The expressions 

4260 are normally instances of :class:`_schema.Column`, but may also 

4261 be arbitrary SQL expressions which ultimately refer to a 

4262 :class:`_schema.Column`. 

4263 

4264 :param unique=False: 

4265 Keyword only argument; if True, create a unique index. 

4266 

4267 :param quote=None: 

4268 Keyword only argument; whether to apply quoting to the name of 

4269 the index. Works in the same manner as that of 

4270 :paramref:`_schema.Column.quote`. 

4271 

4272 :param info=None: Optional data dictionary which will be populated 

4273 into the :attr:`.SchemaItem.info` attribute of this object. 

4274 

4275 .. versionadded:: 1.0.0 

4276 

4277 :param \**kw: Additional keyword arguments not mentioned above are 

4278 dialect specific, and passed in the form 

4279 ``<dialectname>_<argname>``. See the documentation regarding an 

4280 individual dialect at :ref:`dialect_toplevel` for detail on 

4281 documented arguments. 

4282 

4283 """ 

4284 self.table = table = None 

4285 

4286 self.name = quoted_name(name, kw.pop("quote", None)) 

4287 self.unique = kw.pop("unique", False) 

4288 _column_flag = kw.pop("_column_flag", False) 

4289 if "info" in kw: 

4290 self.info = kw.pop("info") 

4291 

4292 # TODO: consider "table" argument being public, but for 

4293 # the purpose of the fix here, it starts as private. 

4294 if "_table" in kw: 

4295 table = kw.pop("_table") 

4296 

4297 self._validate_dialect_kwargs(kw) 

4298 

4299 self.expressions = [] 

4300 # will call _set_parent() if table-bound column 

4301 # objects are present 

4302 ColumnCollectionMixin.__init__( 

4303 self, 

4304 *expressions, 

4305 _column_flag=_column_flag, 

4306 _gather_expressions=self.expressions 

4307 ) 

4308 

4309 if table is not None: 

4310 self._set_parent(table) 

4311 

4312 def _set_parent(self, table, **kw): 

4313 ColumnCollectionMixin._set_parent(self, table) 

4314 

4315 if self.table is not None and table is not self.table: 

4316 raise exc.ArgumentError( 

4317 "Index '%s' is against table '%s', and " 

4318 "cannot be associated with table '%s'." 

4319 % (self.name, self.table.description, table.description) 

4320 ) 

4321 self.table = table 

4322 table.indexes.add(self) 

4323 

4324 expressions = self.expressions 

4325 col_expressions = self._col_expressions(table) 

4326 assert len(expressions) == len(col_expressions) 

4327 self.expressions = [ 

4328 expr if isinstance(expr, ClauseElement) else colexpr 

4329 for expr, colexpr in zip(expressions, col_expressions) 

4330 ] 

4331 

4332 @property 

4333 def bind(self): 

4334 """Return the connectable associated with this Index.""" 

4335 

4336 return self.table.bind 

4337 

4338 def create(self, bind=None, checkfirst=False): 

4339 """Issue a ``CREATE`` statement for this 

4340 :class:`.Index`, using the given :class:`.Connectable` 

4341 for connectivity. 

4342 

4343 .. note:: the "bind" argument will be required in 

4344 SQLAlchemy 2.0. 

4345 

4346 .. seealso:: 

4347 

4348 :meth:`_schema.MetaData.create_all`. 

4349 

4350 """ 

4351 if bind is None: 

4352 bind = _bind_or_error(self) 

4353 bind._run_ddl_visitor(ddl.SchemaGenerator, self, checkfirst=checkfirst) 

4354 return self 

4355 

4356 def drop(self, bind=None, checkfirst=False): 

4357 """Issue a ``DROP`` statement for this 

4358 :class:`.Index`, using the given :class:`.Connectable` 

4359 for connectivity. 

4360 

4361 .. note:: the "bind" argument will be required in 

4362 SQLAlchemy 2.0. 

4363 

4364 .. seealso:: 

4365 

4366 :meth:`_schema.MetaData.drop_all`. 

4367 

4368 """ 

4369 if bind is None: 

4370 bind = _bind_or_error(self) 

4371 bind._run_ddl_visitor(ddl.SchemaDropper, self, checkfirst=checkfirst) 

4372 

4373 def __repr__(self): 

4374 return "Index(%s)" % ( 

4375 ", ".join( 

4376 [repr(self.name)] 

4377 + [repr(e) for e in self.expressions] 

4378 + (self.unique and ["unique=True"] or []) 

4379 ) 

4380 ) 

4381 

4382 

4383DEFAULT_NAMING_CONVENTION = util.immutabledict({"ix": "ix_%(column_0_label)s"}) 

4384 

4385 

4386class MetaData(SchemaItem): 

4387 """A collection of :class:`_schema.Table` 

4388 objects and their associated schema 

4389 constructs. 

4390 

4391 Holds a collection of :class:`_schema.Table` objects as well as 

4392 an optional binding to an :class:`_engine.Engine` or 

4393 :class:`_engine.Connection`. If bound, the :class:`_schema.Table` objects 

4394 in the collection and their columns may participate in implicit SQL 

4395 execution. 

4396 

4397 The :class:`_schema.Table` objects themselves are stored in the 

4398 :attr:`_schema.MetaData.tables` dictionary. 

4399 

4400 :class:`_schema.MetaData` is a thread-safe object for read operations. 

4401 Construction of new tables within a single :class:`_schema.MetaData` 

4402 object, 

4403 either explicitly or via reflection, may not be completely thread-safe. 

4404 

4405 .. seealso:: 

4406 

4407 :ref:`metadata_describing` - Introduction to database metadata 

4408 

4409 """ 

4410 

4411 __visit_name__ = "metadata" 

4412 

4413 @util.deprecated_params( 

4414 bind=( 

4415 "2.0", 

4416 "The :paramref:`_schema.MetaData.bind` argument is deprecated and " 

4417 "will be removed in SQLAlchemy 2.0.", 

4418 ), 

4419 ) 

4420 def __init__( 

4421 self, 

4422 bind=None, 

4423 schema=None, 

4424 quote_schema=None, 

4425 naming_convention=None, 

4426 info=None, 

4427 ): 

4428 """Create a new MetaData object. 

4429 

4430 :param bind: 

4431 An Engine or Connection to bind to. May also be a string or URL 

4432 instance, these are passed to :func:`_sa.create_engine` and 

4433 this :class:`_schema.MetaData` will 

4434 be bound to the resulting engine. 

4435 

4436 :param schema: 

4437 The default schema to use for the :class:`_schema.Table`, 

4438 :class:`.Sequence`, and potentially other objects associated with 

4439 this :class:`_schema.MetaData`. Defaults to ``None``. 

4440 

4441 .. seealso:: 

4442 

4443 :ref:`schema_metadata_schema_name` - details on how the 

4444 :paramref:`_schema.MetaData.schema` parameter is used. 

4445 

4446 :paramref:`_schema.Table.schema` 

4447 

4448 :paramref:`.Sequence.schema` 

4449 

4450 :param quote_schema: 

4451 Sets the ``quote_schema`` flag for those :class:`_schema.Table`, 

4452 :class:`.Sequence`, and other objects which make usage of the 

4453 local ``schema`` name. 

4454 

4455 :param info: Optional data dictionary which will be populated into the 

4456 :attr:`.SchemaItem.info` attribute of this object. 

4457 

4458 .. versionadded:: 1.0.0 

4459 

4460 :param naming_convention: a dictionary referring to values which 

4461 will establish default naming conventions for :class:`.Constraint` 

4462 and :class:`.Index` objects, for those objects which are not given 

4463 a name explicitly. 

4464 

4465 The keys of this dictionary may be: 

4466 

4467 * a constraint or Index class, e.g. the :class:`.UniqueConstraint`, 

4468 :class:`_schema.ForeignKeyConstraint` class, the :class:`.Index` 

4469 class 

4470 

4471 * a string mnemonic for one of the known constraint classes; 

4472 ``"fk"``, ``"pk"``, ``"ix"``, ``"ck"``, ``"uq"`` for foreign key, 

4473 primary key, index, check, and unique constraint, respectively. 

4474 

4475 * the string name of a user-defined "token" that can be used 

4476 to define new naming tokens. 

4477 

4478 The values associated with each "constraint class" or "constraint 

4479 mnemonic" key are string naming templates, such as 

4480 ``"uq_%(table_name)s_%(column_0_name)s"``, 

4481 which describe how the name should be composed. The values 

4482 associated with user-defined "token" keys should be callables of the 

4483 form ``fn(constraint, table)``, which accepts the constraint/index 

4484 object and :class:`_schema.Table` as arguments, returning a string 

4485 result. 

4486 

4487 The built-in names are as follows, some of which may only be 

4488 available for certain types of constraint: 

4489 

4490 * ``%(table_name)s`` - the name of the :class:`_schema.Table` 

4491 object 

4492 associated with the constraint. 

4493 

4494 * ``%(referred_table_name)s`` - the name of the 

4495 :class:`_schema.Table` 

4496 object associated with the referencing target of a 

4497 :class:`_schema.ForeignKeyConstraint`. 

4498 

4499 * ``%(column_0_name)s`` - the name of the :class:`_schema.Column` 

4500 at 

4501 index position "0" within the constraint. 

4502 

4503 * ``%(column_0N_name)s`` - the name of all :class:`_schema.Column` 

4504 objects in order within the constraint, joined without a 

4505 separator. 

4506 

4507 * ``%(column_0_N_name)s`` - the name of all 

4508 :class:`_schema.Column` 

4509 objects in order within the constraint, joined with an 

4510 underscore as a separator. 

4511 

4512 * ``%(column_0_label)s``, ``%(column_0N_label)s``, 

4513 ``%(column_0_N_label)s`` - the label of either the zeroth 

4514 :class:`_schema.Column` or all :class:`.Columns`, separated with 

4515 or without an underscore 

4516 

4517 * ``%(column_0_key)s``, ``%(column_0N_key)s``, 

4518 ``%(column_0_N_key)s`` - the key of either the zeroth 

4519 :class:`_schema.Column` or all :class:`.Columns`, separated with 

4520 or without an underscore 

4521 

4522 * ``%(referred_column_0_name)s``, ``%(referred_column_0N_name)s`` 

4523 ``%(referred_column_0_N_name)s``, ``%(referred_column_0_key)s``, 

4524 ``%(referred_column_0N_key)s``, ... column tokens which 

4525 render the names/keys/labels of columns that are referenced 

4526 by a :class:`_schema.ForeignKeyConstraint`. 

4527 

4528 * ``%(constraint_name)s`` - a special key that refers to the 

4529 existing name given to the constraint. When this key is 

4530 present, the :class:`.Constraint` object's existing name will be 

4531 replaced with one that is composed from template string that 

4532 uses this token. When this token is present, it is required that 

4533 the :class:`.Constraint` is given an explicit name ahead of time. 

4534 

4535 * user-defined: any additional token may be implemented by passing 

4536 it along with a ``fn(constraint, table)`` callable to the 

4537 naming_convention dictionary. 

4538 

4539 .. versionadded:: 1.3.0 - added new ``%(column_0N_name)s``, 

4540 ``%(column_0_N_name)s``, and related tokens that produce 

4541 concatenations of names, keys, or labels for all columns referred 

4542 to by a given constraint. 

4543 

4544 .. seealso:: 

4545 

4546 :ref:`constraint_naming_conventions` - for detailed usage 

4547 examples. 

4548 

4549 """ 

4550 self.tables = util.FacadeDict() 

4551 self.schema = quoted_name(schema, quote_schema) 

4552 self.naming_convention = ( 

4553 naming_convention 

4554 if naming_convention 

4555 else DEFAULT_NAMING_CONVENTION 

4556 ) 

4557 if info: 

4558 self.info = info 

4559 self._schemas = set() 

4560 self._sequences = {} 

4561 self._fk_memos = collections.defaultdict(list) 

4562 

4563 self.bind = bind 

4564 

4565 tables = None 

4566 """A dictionary of :class:`_schema.Table` 

4567 objects keyed to their name or "table key". 

4568 

4569 The exact key is that determined by the :attr:`_schema.Table.key` 

4570 attribute; 

4571 for a table with no :attr:`_schema.Table.schema` attribute, 

4572 this is the same 

4573 as :attr:`_schema.Table.name`. For a table with a schema, 

4574 it is typically of the 

4575 form ``schemaname.tablename``. 

4576 

4577 .. seealso:: 

4578 

4579 :attr:`_schema.MetaData.sorted_tables` 

4580 

4581 """ 

4582 

4583 def __repr__(self): 

4584 if self.bind: 

4585 return "MetaData(bind=%r)" % self.bind 

4586 else: 

4587 return "MetaData()" 

4588 

4589 def __contains__(self, table_or_key): 

4590 if not isinstance(table_or_key, util.string_types): 

4591 table_or_key = table_or_key.key 

4592 return table_or_key in self.tables 

4593 

4594 def _add_table(self, name, schema, table): 

4595 key = _get_table_key(name, schema) 

4596 self.tables._insert_item(key, table) 

4597 if schema: 

4598 self._schemas.add(schema) 

4599 

4600 def _remove_table(self, name, schema): 

4601 key = _get_table_key(name, schema) 

4602 removed = dict.pop(self.tables, key, None) 

4603 if removed is not None: 

4604 for fk in removed.foreign_keys: 

4605 fk._remove_from_metadata(self) 

4606 if self._schemas: 

4607 self._schemas = set( 

4608 [ 

4609 t.schema 

4610 for t in self.tables.values() 

4611 if t.schema is not None 

4612 ] 

4613 ) 

4614 

4615 def __getstate__(self): 

4616 return { 

4617 "tables": self.tables, 

4618 "schema": self.schema, 

4619 "schemas": self._schemas, 

4620 "sequences": self._sequences, 

4621 "fk_memos": self._fk_memos, 

4622 "naming_convention": self.naming_convention, 

4623 } 

4624 

4625 def __setstate__(self, state): 

4626 self.tables = state["tables"] 

4627 self.schema = state["schema"] 

4628 self.naming_convention = state["naming_convention"] 

4629 self._bind = None 

4630 self._sequences = state["sequences"] 

4631 self._schemas = state["schemas"] 

4632 self._fk_memos = state["fk_memos"] 

4633 

4634 def is_bound(self): 

4635 """True if this MetaData is bound to an Engine or Connection.""" 

4636 

4637 return self._bind is not None 

4638 

4639 def bind(self): 

4640 """An :class:`_engine.Engine` or :class:`_engine.Connection` 

4641 to which this 

4642 :class:`_schema.MetaData` is bound. 

4643 

4644 Typically, a :class:`_engine.Engine` is assigned to this attribute 

4645 so that "implicit execution" may be used, or alternatively 

4646 as a means of providing engine binding information to an 

4647 ORM :class:`.Session` object:: 

4648 

4649 engine = create_engine("someurl://") 

4650 metadata.bind = engine 

4651 

4652 .. deprecated :: 1.4 

4653 

4654 The metadata.bind attribute, as part of the deprecated system 

4655 of "implicit execution", is itself deprecated and will be 

4656 removed in SQLAlchemy 2.0. 

4657 

4658 .. seealso:: 

4659 

4660 :ref:`dbengine_implicit` - background on "bound metadata" 

4661 

4662 """ 

4663 return self._bind 

4664 

4665 @util.preload_module("sqlalchemy.engine.url") 

4666 def _bind_to(self, bind): 

4667 """Bind this MetaData to an Engine, Connection, string or URL.""" 

4668 url = util.preloaded.engine_url 

4669 if isinstance(bind, util.string_types + (url.URL,)): 

4670 self._bind = sqlalchemy.create_engine(bind) 

4671 else: 

4672 self._bind = bind 

4673 

4674 bind = property(bind, _bind_to) 

4675 

4676 def clear(self): 

4677 """Clear all Table objects from this MetaData.""" 

4678 

4679 dict.clear(self.tables) 

4680 self._schemas.clear() 

4681 self._fk_memos.clear() 

4682 

4683 def remove(self, table): 

4684 """Remove the given Table object from this MetaData.""" 

4685 

4686 self._remove_table(table.name, table.schema) 

4687 

4688 @property 

4689 def sorted_tables(self): 

4690 """Returns a list of :class:`_schema.Table` objects sorted in order of 

4691 foreign key dependency. 

4692 

4693 The sorting will place :class:`_schema.Table` 

4694 objects that have dependencies 

4695 first, before the dependencies themselves, representing the 

4696 order in which they can be created. To get the order in which 

4697 the tables would be dropped, use the ``reversed()`` Python built-in. 

4698 

4699 .. warning:: 

4700 

4701 The :attr:`.MetaData.sorted_tables` attribute cannot by itself 

4702 accommodate automatic resolution of dependency cycles between 

4703 tables, which are usually caused by mutually dependent foreign key 

4704 constraints. When these cycles are detected, the foreign keys 

4705 of these tables are omitted from consideration in the sort. 

4706 A warning is emitted when this condition occurs, which will be an 

4707 exception raise in a future release. Tables which are not part 

4708 of the cycle will still be returned in dependency order. 

4709 

4710 To resolve these cycles, the 

4711 :paramref:`_schema.ForeignKeyConstraint.use_alter` parameter may be 

4712 applied to those constraints which create a cycle. Alternatively, 

4713 the :func:`_schema.sort_tables_and_constraints` function will 

4714 automatically return foreign key constraints in a separate 

4715 collection when cycles are detected so that they may be applied 

4716 to a schema separately. 

4717 

4718 .. versionchanged:: 1.3.17 - a warning is emitted when 

4719 :attr:`.MetaData.sorted_tables` cannot perform a proper sort 

4720 due to cyclical dependencies. This will be an exception in a 

4721 future release. Additionally, the sort will continue to return 

4722 other tables not involved in the cycle in dependency order which 

4723 was not the case previously. 

4724 

4725 .. seealso:: 

4726 

4727 :func:`_schema.sort_tables` 

4728 

4729 :func:`_schema.sort_tables_and_constraints` 

4730 

4731 :attr:`_schema.MetaData.tables` 

4732 

4733 :meth:`_reflection.Inspector.get_table_names` 

4734 

4735 :meth:`_reflection.Inspector.get_sorted_table_and_fkc_names` 

4736 

4737 

4738 """ 

4739 return ddl.sort_tables( 

4740 sorted(self.tables.values(), key=lambda t: t.key) 

4741 ) 

4742 

4743 def reflect( 

4744 self, 

4745 bind=None, 

4746 schema=None, 

4747 views=False, 

4748 only=None, 

4749 extend_existing=False, 

4750 autoload_replace=True, 

4751 resolve_fks=True, 

4752 **dialect_kwargs 

4753 ): 

4754 r"""Load all available table definitions from the database. 

4755 

4756 Automatically creates ``Table`` entries in this ``MetaData`` for any 

4757 table available in the database but not yet present in the 

4758 ``MetaData``. May be called multiple times to pick up tables recently 

4759 added to the database, however no special action is taken if a table 

4760 in this ``MetaData`` no longer exists in the database. 

4761 

4762 :param bind: 

4763 A :class:`.Connectable` used to access the database; if None, uses 

4764 the existing bind on this ``MetaData``, if any. 

4765 

4766 .. note:: the "bind" argument will be required in 

4767 SQLAlchemy 2.0. 

4768 

4769 :param schema: 

4770 Optional, query and reflect tables from an alternate schema. 

4771 If None, the schema associated with this :class:`_schema.MetaData` 

4772 is used, if any. 

4773 

4774 :param views: 

4775 If True, also reflect views. 

4776 

4777 :param only: 

4778 Optional. Load only a sub-set of available named tables. May be 

4779 specified as a sequence of names or a callable. 

4780 

4781 If a sequence of names is provided, only those tables will be 

4782 reflected. An error is raised if a table is requested but not 

4783 available. Named tables already present in this ``MetaData`` are 

4784 ignored. 

4785 

4786 If a callable is provided, it will be used as a boolean predicate to 

4787 filter the list of potential table names. The callable is called 

4788 with a table name and this ``MetaData`` instance as positional 

4789 arguments and should return a true value for any table to reflect. 

4790 

4791 :param extend_existing: Passed along to each :class:`_schema.Table` as 

4792 :paramref:`_schema.Table.extend_existing`. 

4793 

4794 .. versionadded:: 0.9.1 

4795 

4796 :param autoload_replace: Passed along to each :class:`_schema.Table` 

4797 as 

4798 :paramref:`_schema.Table.autoload_replace`. 

4799 

4800 .. versionadded:: 0.9.1 

4801 

4802 :param resolve_fks: if True, reflect :class:`_schema.Table` 

4803 objects linked 

4804 to :class:`_schema.ForeignKey` objects located in each 

4805 :class:`_schema.Table`. 

4806 For :meth:`_schema.MetaData.reflect`, 

4807 this has the effect of reflecting 

4808 related tables that might otherwise not be in the list of tables 

4809 being reflected, for example if the referenced table is in a 

4810 different schema or is omitted via the 

4811 :paramref:`.MetaData.reflect.only` parameter. When False, 

4812 :class:`_schema.ForeignKey` objects are not followed to the 

4813 :class:`_schema.Table` 

4814 in which they link, however if the related table is also part of the 

4815 list of tables that would be reflected in any case, the 

4816 :class:`_schema.ForeignKey` object will still resolve to its related 

4817 :class:`_schema.Table` after the :meth:`_schema.MetaData.reflect` 

4818 operation is 

4819 complete. Defaults to True. 

4820 

4821 .. versionadded:: 1.3.0 

4822 

4823 .. seealso:: 

4824 

4825 :paramref:`_schema.Table.resolve_fks` 

4826 

4827 :param \**dialect_kwargs: Additional keyword arguments not mentioned 

4828 above are dialect specific, and passed in the form 

4829 ``<dialectname>_<argname>``. See the documentation regarding an 

4830 individual dialect at :ref:`dialect_toplevel` for detail on 

4831 documented arguments. 

4832 

4833 .. versionadded:: 0.9.2 - Added 

4834 :paramref:`.MetaData.reflect.**dialect_kwargs` to support 

4835 dialect-level reflection options for all :class:`_schema.Table` 

4836 objects reflected. 

4837 

4838 """ 

4839 if bind is None: 

4840 bind = _bind_or_error(self) 

4841 

4842 with inspection.inspect(bind)._inspection_context() as insp: 

4843 reflect_opts = { 

4844 "autoload_with": insp, 

4845 "extend_existing": extend_existing, 

4846 "autoload_replace": autoload_replace, 

4847 "resolve_fks": resolve_fks, 

4848 "_extend_on": set(), 

4849 } 

4850 

4851 reflect_opts.update(dialect_kwargs) 

4852 

4853 if schema is None: 

4854 schema = self.schema 

4855 

4856 if schema is not None: 

4857 reflect_opts["schema"] = schema 

4858 

4859 available = util.OrderedSet(insp.get_table_names(schema)) 

4860 if views: 

4861 available.update(insp.get_view_names(schema)) 

4862 

4863 if schema is not None: 

4864 available_w_schema = util.OrderedSet( 

4865 ["%s.%s" % (schema, name) for name in available] 

4866 ) 

4867 else: 

4868 available_w_schema = available 

4869 

4870 current = set(self.tables) 

4871 

4872 if only is None: 

4873 load = [ 

4874 name 

4875 for name, schname in zip(available, available_w_schema) 

4876 if extend_existing or schname not in current 

4877 ] 

4878 elif callable(only): 

4879 load = [ 

4880 name 

4881 for name, schname in zip(available, available_w_schema) 

4882 if (extend_existing or schname not in current) 

4883 and only(name, self) 

4884 ] 

4885 else: 

4886 missing = [name for name in only if name not in available] 

4887 if missing: 

4888 s = schema and (" schema '%s'" % schema) or "" 

4889 raise exc.InvalidRequestError( 

4890 "Could not reflect: requested table(s) not available " 

4891 "in %r%s: (%s)" % (bind.engine, s, ", ".join(missing)) 

4892 ) 

4893 load = [ 

4894 name 

4895 for name in only 

4896 if extend_existing or name not in current 

4897 ] 

4898 

4899 for name in load: 

4900 try: 

4901 Table(name, self, **reflect_opts) 

4902 except exc.UnreflectableTableError as uerr: 

4903 util.warn("Skipping table %s: %s" % (name, uerr)) 

4904 

4905 def create_all(self, bind=None, tables=None, checkfirst=True): 

4906 """Create all tables stored in this metadata. 

4907 

4908 Conditional by default, will not attempt to recreate tables already 

4909 present in the target database. 

4910 

4911 :param bind: 

4912 A :class:`.Connectable` used to access the 

4913 database; if None, uses the existing bind on this ``MetaData``, if 

4914 any. 

4915 

4916 .. note:: the "bind" argument will be required in 

4917 SQLAlchemy 2.0. 

4918 

4919 :param tables: 

4920 Optional list of ``Table`` objects, which is a subset of the total 

4921 tables in the ``MetaData`` (others are ignored). 

4922 

4923 :param checkfirst: 

4924 Defaults to True, don't issue CREATEs for tables already present 

4925 in the target database. 

4926 

4927 """ 

4928 if bind is None: 

4929 bind = _bind_or_error(self) 

4930 bind._run_ddl_visitor( 

4931 ddl.SchemaGenerator, self, checkfirst=checkfirst, tables=tables 

4932 ) 

4933 

4934 def drop_all(self, bind=None, tables=None, checkfirst=True): 

4935 """Drop all tables stored in this metadata. 

4936 

4937 Conditional by default, will not attempt to drop tables not present in 

4938 the target database. 

4939 

4940 :param bind: 

4941 A :class:`.Connectable` used to access the 

4942 database; if None, uses the existing bind on this ``MetaData``, if 

4943 any. 

4944 

4945 .. note:: the "bind" argument will be required in 

4946 SQLAlchemy 2.0. 

4947 

4948 :param tables: 

4949 Optional list of ``Table`` objects, which is a subset of the 

4950 total tables in the ``MetaData`` (others are ignored). 

4951 

4952 :param checkfirst: 

4953 Defaults to True, only issue DROPs for tables confirmed to be 

4954 present in the target database. 

4955 

4956 """ 

4957 if bind is None: 

4958 bind = _bind_or_error(self) 

4959 bind._run_ddl_visitor( 

4960 ddl.SchemaDropper, self, checkfirst=checkfirst, tables=tables 

4961 ) 

4962 

4963 

4964@util.deprecated_cls( 

4965 "1.4", 

4966 ":class:`.ThreadLocalMetaData` is deprecated and will be removed " 

4967 "in a future release.", 

4968 constructor="__init__", 

4969) 

4970class ThreadLocalMetaData(MetaData): 

4971 """A MetaData variant that presents a different ``bind`` in every thread. 

4972 

4973 Makes the ``bind`` property of the MetaData a thread-local value, allowing 

4974 this collection of tables to be bound to different ``Engine`` 

4975 implementations or connections in each thread. 

4976 

4977 The ThreadLocalMetaData starts off bound to None in each thread. Binds 

4978 must be made explicitly by assigning to the ``bind`` property or using 

4979 ``connect()``. You can also re-bind dynamically multiple times per 

4980 thread, just like a regular ``MetaData``. 

4981 

4982 """ 

4983 

4984 __visit_name__ = "metadata" 

4985 

4986 def __init__(self): 

4987 """Construct a ThreadLocalMetaData.""" 

4988 

4989 self.context = util.threading.local() 

4990 self.__engines = {} 

4991 super(ThreadLocalMetaData, self).__init__() 

4992 

4993 def bind(self): 

4994 """The bound Engine or Connection for this thread. 

4995 

4996 This property may be assigned an Engine or Connection, or assigned a 

4997 string or URL to automatically create a basic Engine for this bind 

4998 with ``create_engine()``.""" 

4999 

5000 return getattr(self.context, "_engine", None) 

5001 

5002 @util.preload_module("sqlalchemy.engine.url") 

5003 def _bind_to(self, bind): 

5004 """Bind to a Connectable in the caller's thread.""" 

5005 url = util.preloaded.engine_url 

5006 if isinstance(bind, util.string_types + (url.URL,)): 

5007 try: 

5008 self.context._engine = self.__engines[bind] 

5009 except KeyError: 

5010 e = sqlalchemy.create_engine(bind) 

5011 self.__engines[bind] = e 

5012 self.context._engine = e 

5013 else: 

5014 # TODO: this is squirrely. we shouldn't have to hold onto engines 

5015 # in a case like this 

5016 if bind not in self.__engines: 

5017 self.__engines[bind] = bind 

5018 self.context._engine = bind 

5019 

5020 bind = property(bind, _bind_to) 

5021 

5022 def is_bound(self): 

5023 """True if there is a bind for this thread.""" 

5024 return ( 

5025 hasattr(self.context, "_engine") 

5026 and self.context._engine is not None 

5027 ) 

5028 

5029 def dispose(self): 

5030 """Dispose all bound engines, in all thread contexts.""" 

5031 

5032 for e in self.__engines.values(): 

5033 if hasattr(e, "dispose"): 

5034 e.dispose() 

5035 

5036 

5037class Computed(FetchedValue, SchemaItem): 

5038 """Defines a generated column, i.e. "GENERATED ALWAYS AS" syntax. 

5039 

5040 The :class:`.Computed` construct is an inline construct added to the 

5041 argument list of a :class:`_schema.Column` object:: 

5042 

5043 from sqlalchemy import Computed 

5044 

5045 Table('square', metadata_obj, 

5046 Column('side', Float, nullable=False), 

5047 Column('area', Float, Computed('side * side')) 

5048 ) 

5049 

5050 See the linked documentation below for complete details. 

5051 

5052 .. versionadded:: 1.3.11 

5053 

5054 .. seealso:: 

5055 

5056 :ref:`computed_ddl` 

5057 

5058 """ 

5059 

5060 __visit_name__ = "computed_column" 

5061 

5062 @_document_text_coercion( 

5063 "sqltext", ":class:`.Computed`", ":paramref:`.Computed.sqltext`" 

5064 ) 

5065 def __init__(self, sqltext, persisted=None): 

5066 """Construct a GENERATED ALWAYS AS DDL construct to accompany a 

5067 :class:`_schema.Column`. 

5068 

5069 :param sqltext: 

5070 A string containing the column generation expression, which will be 

5071 used verbatim, or a SQL expression construct, such as a 

5072 :func:`_expression.text` 

5073 object. If given as a string, the object is converted to a 

5074 :func:`_expression.text` object. 

5075 

5076 :param persisted: 

5077 Optional, controls how this column should be persisted by the 

5078 database. Possible values are: 

5079 

5080 * ``None``, the default, it will use the default persistence 

5081 defined by the database. 

5082 * ``True``, will render ``GENERATED ALWAYS AS ... STORED``, or the 

5083 equivalent for the target database if supported. 

5084 * ``False``, will render ``GENERATED ALWAYS AS ... VIRTUAL``, or 

5085 the equivalent for the target database if supported. 

5086 

5087 Specifying ``True`` or ``False`` may raise an error when the DDL 

5088 is emitted to the target database if the database does not support 

5089 that persistence option. Leaving this parameter at its default 

5090 of ``None`` is guaranteed to succeed for all databases that support 

5091 ``GENERATED ALWAYS AS``. 

5092 

5093 """ 

5094 self.sqltext = coercions.expect(roles.DDLExpressionRole, sqltext) 

5095 self.persisted = persisted 

5096 self.column = None 

5097 

5098 def _set_parent(self, parent, **kw): 

5099 if not isinstance( 

5100 parent.server_default, (type(None), Computed) 

5101 ) or not isinstance(parent.server_onupdate, (type(None), Computed)): 

5102 raise exc.ArgumentError( 

5103 "A generated column cannot specify a server_default or a " 

5104 "server_onupdate argument" 

5105 ) 

5106 self.column = parent 

5107 parent.computed = self 

5108 self.column.server_onupdate = self 

5109 self.column.server_default = self 

5110 

5111 def _as_for_update(self, for_update): 

5112 return self 

5113 

5114 @util.deprecated( 

5115 "1.4", 

5116 "The :meth:`_schema.Computed.copy` method is deprecated " 

5117 "and will be removed in a future release.", 

5118 ) 

5119 def copy(self, target_table=None, **kw): 

5120 return self._copy(target_table, **kw) 

5121 

5122 def _copy(self, target_table=None, **kw): 

5123 sqltext = _copy_expression( 

5124 self.sqltext, 

5125 self.column.table if self.column is not None else None, 

5126 target_table, 

5127 ) 

5128 g = Computed(sqltext, persisted=self.persisted) 

5129 

5130 return self._schema_item_copy(g) 

5131 

5132 

5133class Identity(IdentityOptions, FetchedValue, SchemaItem): 

5134 """Defines an identity column, i.e. "GENERATED { ALWAYS | BY DEFAULT } 

5135 AS IDENTITY" syntax. 

5136 

5137 The :class:`.Identity` construct is an inline construct added to the 

5138 argument list of a :class:`_schema.Column` object:: 

5139 

5140 from sqlalchemy import Identity 

5141 

5142 Table('foo', metadata_obj, 

5143 Column('id', Integer, Identity()) 

5144 Column('description', Text), 

5145 ) 

5146 

5147 See the linked documentation below for complete details. 

5148 

5149 .. versionadded:: 1.4 

5150 

5151 .. seealso:: 

5152 

5153 :ref:`identity_ddl` 

5154 

5155 """ 

5156 

5157 __visit_name__ = "identity_column" 

5158 

5159 def __init__( 

5160 self, 

5161 always=False, 

5162 on_null=None, 

5163 start=None, 

5164 increment=None, 

5165 minvalue=None, 

5166 maxvalue=None, 

5167 nominvalue=None, 

5168 nomaxvalue=None, 

5169 cycle=None, 

5170 cache=None, 

5171 order=None, 

5172 ): 

5173 """Construct a GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY DDL 

5174 construct to accompany a :class:`_schema.Column`. 

5175 

5176 See the :class:`.Sequence` documentation for a complete description 

5177 of most parameters. 

5178 

5179 .. note:: 

5180 MSSQL supports this construct as the preferred alternative to 

5181 generate an IDENTITY on a column, but it uses non standard 

5182 syntax that only support :paramref:`_schema.Identity.start` 

5183 and :paramref:`_schema.Identity.increment`. 

5184 All other parameters are ignored. 

5185 

5186 :param always: 

5187 A boolean, that indicates the type of identity column. 

5188 If ``False`` is specified, the default, then the user-specified 

5189 value takes precedence. 

5190 If ``True`` is specified, a user-specified value is not accepted ( 

5191 on some backends, like PostgreSQL, OVERRIDING SYSTEM VALUE, or 

5192 similar, may be specified in an INSERT to override the sequence 

5193 value). 

5194 Some backends also have a default value for this parameter, 

5195 ``None`` can be used to omit rendering this part in the DDL. It 

5196 will be treated as ``False`` if a backend does not have a default 

5197 value. 

5198 

5199 :param on_null: 

5200 Set to ``True`` to specify ON NULL in conjunction with a 

5201 ``always=False`` identity column. This option is only supported on 

5202 some backends, like Oracle. 

5203 

5204 :param start: the starting index of the sequence. 

5205 :param increment: the increment value of the sequence. 

5206 :param minvalue: the minimum value of the sequence. 

5207 :param maxvalue: the maximum value of the sequence. 

5208 :param nominvalue: no minimum value of the sequence. 

5209 :param nomaxvalue: no maximum value of the sequence. 

5210 :param cycle: allows the sequence to wrap around when the maxvalue 

5211 or minvalue has been reached. 

5212 :param cache: optional integer value; number of future values in the 

5213 sequence which are calculated in advance. 

5214 :param order: optional boolean value; if true, renders the 

5215 ORDER keyword. 

5216 

5217 """ 

5218 IdentityOptions.__init__( 

5219 self, 

5220 start=start, 

5221 increment=increment, 

5222 minvalue=minvalue, 

5223 maxvalue=maxvalue, 

5224 nominvalue=nominvalue, 

5225 nomaxvalue=nomaxvalue, 

5226 cycle=cycle, 

5227 cache=cache, 

5228 order=order, 

5229 ) 

5230 self.always = always 

5231 self.on_null = on_null 

5232 self.column = None 

5233 

5234 def _set_parent(self, parent, **kw): 

5235 if not isinstance( 

5236 parent.server_default, (type(None), Identity) 

5237 ) or not isinstance(parent.server_onupdate, type(None)): 

5238 raise exc.ArgumentError( 

5239 "A column with an Identity object cannot specify a " 

5240 "server_default or a server_onupdate argument" 

5241 ) 

5242 if parent.autoincrement is False: 

5243 raise exc.ArgumentError( 

5244 "A column with an Identity object cannot specify " 

5245 "autoincrement=False" 

5246 ) 

5247 self.column = parent 

5248 

5249 parent.identity = self 

5250 if parent._user_defined_nullable is NULL_UNSPECIFIED: 

5251 parent.nullable = False 

5252 

5253 parent.server_default = self 

5254 

5255 def _as_for_update(self, for_update): 

5256 return self 

5257 

5258 @util.deprecated( 

5259 "1.4", 

5260 "The :meth:`_schema.Identity.copy` method is deprecated " 

5261 "and will be removed in a future release.", 

5262 ) 

5263 def copy(self, **kw): 

5264 return self._copy(**kw) 

5265 

5266 def _copy(self, **kw): 

5267 i = Identity( 

5268 always=self.always, 

5269 on_null=self.on_null, 

5270 start=self.start, 

5271 increment=self.increment, 

5272 minvalue=self.minvalue, 

5273 maxvalue=self.maxvalue, 

5274 nominvalue=self.nominvalue, 

5275 nomaxvalue=self.nomaxvalue, 

5276 cycle=self.cycle, 

5277 cache=self.cache, 

5278 order=self.order, 

5279 ) 

5280 

5281 return self._schema_item_copy(i)