Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/SQLAlchemy-1.3.25.dev0-py3.11-linux-x86_64.egg/sqlalchemy/engine/interfaces.py: 65%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

182 statements  

1# engine/interfaces.py 

2# Copyright (C) 2005-2021 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: http://www.opensource.org/licenses/mit-license.php 

7 

8"""Define core interfaces used by the engine system.""" 

9 

10from .. import util 

11from ..sql.compiler import Compiled # noqa 

12from ..sql.compiler import TypeCompiler # noqa 

13 

14 

15class Dialect(object): 

16 """Define the behavior of a specific database and DB-API combination. 

17 

18 Any aspect of metadata definition, SQL query generation, 

19 execution, result-set handling, or anything else which varies 

20 between databases is defined under the general category of the 

21 Dialect. The Dialect acts as a factory for other 

22 database-specific object implementations including 

23 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. 

24 

25 .. note:: Third party dialects should not subclass :class:`.Dialect` 

26 directly. Instead, subclass :class:`.default.DefaultDialect` or 

27 descendant class. 

28 

29 All dialects include the following attributes. There are many other 

30 attributes that may be supported as well: 

31 

32 ``name`` 

33 identifying name for the dialect from a DBAPI-neutral point of view 

34 (i.e. 'sqlite') 

35 

36 ``driver`` 

37 identifying name for the dialect's DBAPI 

38 

39 ``positional`` 

40 True if the paramstyle for this Dialect is positional. 

41 

42 ``paramstyle`` 

43 the paramstyle to be used (some DB-APIs support multiple 

44 paramstyles). 

45 

46 ``encoding`` 

47 type of encoding to use for unicode, usually defaults to 

48 'utf-8'. 

49 

50 ``statement_compiler`` 

51 a :class:`.Compiled` class used to compile SQL statements 

52 

53 ``ddl_compiler`` 

54 a :class:`.Compiled` class used to compile DDL statements 

55 

56 ``server_version_info`` 

57 a tuple containing a version number for the DB backend in use. 

58 This value is only available for supporting dialects, and is 

59 typically populated during the initial connection to the database. 

60 

61 ``default_schema_name`` 

62 the name of the default schema. This value is only available for 

63 supporting dialects, and is typically populated during the 

64 initial connection to the database. 

65 

66 ``execution_ctx_cls`` 

67 a :class:`.ExecutionContext` class used to handle statement execution 

68 

69 ``execute_sequence_format`` 

70 either the 'tuple' or 'list' type, depending on what cursor.execute() 

71 accepts for the second argument (they vary). 

72 

73 ``preparer`` 

74 a :class:`~sqlalchemy.sql.compiler.IdentifierPreparer` class used to 

75 quote identifiers. 

76 

77 ``supports_alter`` 

78 ``True`` if the database supports ``ALTER TABLE`` - used only for 

79 generating foreign key constraints in certain circumstances 

80 

81 ``max_identifier_length`` 

82 The maximum length of identifier names. 

83 

84 ``supports_sane_rowcount`` 

85 Indicate whether the dialect properly implements rowcount for 

86 ``UPDATE`` and ``DELETE`` statements. 

87 

88 ``supports_sane_multi_rowcount`` 

89 Indicate whether the dialect properly implements rowcount for 

90 ``UPDATE`` and ``DELETE`` statements when executed via 

91 executemany. 

92 

93 ``preexecute_autoincrement_sequences`` 

94 True if 'implicit' primary key functions must be executed separately 

95 in order to get their value. This is currently oriented towards 

96 PostgreSQL. 

97 

98 ``implicit_returning`` 

99 use RETURNING or equivalent during INSERT execution in order to load 

100 newly generated primary keys and other column defaults in one execution, 

101 which are then available via inserted_primary_key. 

102 If an insert statement has returning() specified explicitly, 

103 the "implicit" functionality is not used and inserted_primary_key 

104 will not be available. 

105 

106 ``colspecs`` 

107 A dictionary of TypeEngine classes from sqlalchemy.types mapped 

108 to subclasses that are specific to the dialect class. This 

109 dictionary is class-level only and is not accessed from the 

110 dialect instance itself. 

111 

112 ``supports_default_values`` 

113 Indicates if the construct ``INSERT INTO tablename DEFAULT 

114 VALUES`` is supported 

115 

116 ``supports_sequences`` 

117 Indicates if the dialect supports CREATE SEQUENCE or similar. 

118 

119 ``sequences_optional`` 

120 If True, indicates if the "optional" flag on the Sequence() construct 

121 should signal to not generate a CREATE SEQUENCE. Applies only to 

122 dialects that support sequences. Currently used only to allow PostgreSQL 

123 SERIAL to be used on a column that specifies Sequence() for usage on 

124 other backends. 

125 

126 ``supports_native_enum`` 

127 Indicates if the dialect supports a native ENUM construct. 

128 This will prevent types.Enum from generating a CHECK 

129 constraint when that type is used. 

130 

131 ``supports_native_boolean`` 

132 Indicates if the dialect supports a native boolean construct. 

133 This will prevent types.Boolean from generating a CHECK 

134 constraint when that type is used. 

135 

136 ``dbapi_exception_translation_map`` 

137 A dictionary of names that will contain as values the names of 

138 pep-249 exceptions ("IntegrityError", "OperationalError", etc) 

139 keyed to alternate class names, to support the case where a 

140 DBAPI has exception classes that aren't named as they are 

141 referred to (e.g. IntegrityError = MyException). In the vast 

142 majority of cases this dictionary is empty. 

143 

144 .. versionadded:: 1.0.5 

145 

146 """ 

147 

148 _has_events = False 

149 

150 def create_connect_args(self, url): 

151 """Build DB-API compatible connection arguments. 

152 

153 Given a :class:`.URL` object, returns a tuple 

154 consisting of a ``(*args, **kwargs)`` suitable to send directly 

155 to the dbapi's connect function. The arguments are sent to the 

156 :meth:`.Dialect.connect` method which then runs the DBAPI-level 

157 ``connect()`` function. 

158 

159 The method typically makes use of the 

160 :meth:`.URL.translate_connect_args` 

161 method in order to generate a dictionary of options. 

162 

163 The default implementation is:: 

164 

165 def create_connect_args(self, url): 

166 opts = url.translate_connect_args() 

167 opts.update(url.query) 

168 return [[], opts] 

169 

170 :param url: a :class:`.URL` object 

171 

172 :return: a tuple of ``(*args, **kwargs)`` which will be passed to the 

173 :meth:`.Dialect.connect` method. 

174 

175 .. seealso:: 

176 

177 :meth:`.URL.translate_connect_args` 

178 

179 """ 

180 

181 raise NotImplementedError() 

182 

183 @classmethod 

184 def type_descriptor(cls, typeobj): 

185 """Transform a generic type to a dialect-specific type. 

186 

187 Dialect classes will usually use the 

188 :func:`_types.adapt_type` function in the types module to 

189 accomplish this. 

190 

191 The returned result is cached *per dialect class* so can 

192 contain no dialect-instance state. 

193 

194 """ 

195 

196 raise NotImplementedError() 

197 

198 def initialize(self, connection): 

199 """Called during strategized creation of the dialect with a 

200 connection. 

201 

202 Allows dialects to configure options based on server version info or 

203 other properties. 

204 

205 The connection passed here is a SQLAlchemy Connection object, 

206 with full capabilities. 

207 

208 The initialize() method of the base dialect should be called via 

209 super(). 

210 

211 """ 

212 

213 pass 

214 

215 def reflecttable( 

216 self, connection, table, include_columns, exclude_columns, resolve_fks 

217 ): 

218 """Load table description from the database. 

219 

220 Given a :class:`_engine.Connection` and a 

221 :class:`~sqlalchemy.schema.Table` object, reflect its columns and 

222 properties from the database. 

223 

224 The implementation of this method is provided by 

225 :meth:`.DefaultDialect.reflecttable`, which makes use of 

226 :class:`_reflection.Inspector` to retrieve column information. 

227 

228 Dialects should **not** seek to implement this method, and should 

229 instead implement individual schema inspection operations such as 

230 :meth:`.Dialect.get_columns`, :meth:`.Dialect.get_pk_constraint`, 

231 etc. 

232 

233 """ 

234 

235 raise NotImplementedError() 

236 

237 def get_columns(self, connection, table_name, schema=None, **kw): 

238 """Return information about columns in `table_name`. 

239 

240 Given a :class:`_engine.Connection`, a string 

241 `table_name`, and an optional string `schema`, return column 

242 information as a list of dictionaries with these keys: 

243 

244 * ``name`` - 

245 the column's name 

246 

247 * ``type`` - 

248 [sqlalchemy.types#TypeEngine] 

249 

250 * ``nullable`` - 

251 boolean 

252 

253 * ``default`` - 

254 the column's default value 

255 

256 * ``autoincrement`` - 

257 boolean 

258 

259 * ``sequence`` - 

260 a dictionary of the form 

261 {'name' : str, 'start' :int, 'increment': int, 'minvalue': int, 

262 'maxvalue': int, 'nominvalue': bool, 'nomaxvalue': bool, 

263 'cycle': bool, 'cache': int, 'order': bool} 

264 

265 Additional column attributes may be present. 

266 

267 """ 

268 

269 raise NotImplementedError() 

270 

271 @util.deprecated( 

272 "0.8", 

273 "The :meth:`.Dialect.get_primary_keys` method is deprecated and " 

274 "will be removed in a future release. Please refer to the " 

275 ":meth:`.Dialect.get_pk_constraint` method. ", 

276 ) 

277 def get_primary_keys(self, connection, table_name, schema=None, **kw): 

278 """Return information about primary keys in `table_name`.""" 

279 

280 raise NotImplementedError() 

281 

282 def get_pk_constraint(self, connection, table_name, schema=None, **kw): 

283 """Return information about the primary key constraint on 

284 table_name`. 

285 

286 Given a :class:`_engine.Connection`, a string 

287 `table_name`, and an optional string `schema`, return primary 

288 key information as a dictionary with these keys: 

289 

290 * ``constrained_columns`` - 

291 a list of column names that make up the primary key 

292 

293 * ``name`` - 

294 optional name of the primary key constraint. 

295 

296 """ 

297 raise NotImplementedError() 

298 

299 def get_foreign_keys(self, connection, table_name, schema=None, **kw): 

300 """Return information about foreign_keys in `table_name`. 

301 

302 Given a :class:`_engine.Connection`, a string 

303 `table_name`, and an optional string `schema`, return foreign 

304 key information as a list of dicts with these keys: 

305 

306 * ``name`` - 

307 the constraint's name 

308 

309 * ``constrained_columns`` - 

310 a list of column names that make up the foreign key 

311 

312 * ``referred_schema`` - 

313 the name of the referred schema 

314 

315 * ``referred_table`` - 

316 the name of the referred table 

317 

318 * ``referred_columns`` - 

319 a list of column names in the referred table that correspond to 

320 constrained_columns 

321 """ 

322 

323 raise NotImplementedError() 

324 

325 def get_table_names(self, connection, schema=None, **kw): 

326 """Return a list of table names for `schema`.""" 

327 

328 raise NotImplementedError() 

329 

330 def get_temp_table_names(self, connection, schema=None, **kw): 

331 """Return a list of temporary table names on the given connection, 

332 if supported by the underlying backend. 

333 

334 """ 

335 

336 raise NotImplementedError() 

337 

338 def get_view_names(self, connection, schema=None, **kw): 

339 """Return a list of all view names available in the database. 

340 

341 :param schema: 

342 Optional, retrieve names from a non-default schema. 

343 """ 

344 

345 raise NotImplementedError() 

346 

347 def get_temp_view_names(self, connection, schema=None, **kw): 

348 """Return a list of temporary view names on the given connection, 

349 if supported by the underlying backend. 

350 

351 """ 

352 

353 raise NotImplementedError() 

354 

355 def get_view_definition(self, connection, view_name, schema=None, **kw): 

356 """Return view definition. 

357 

358 Given a :class:`_engine.Connection`, a string 

359 `view_name`, and an optional string `schema`, return the view 

360 definition. 

361 """ 

362 

363 raise NotImplementedError() 

364 

365 def get_indexes(self, connection, table_name, schema=None, **kw): 

366 """Return information about indexes in `table_name`. 

367 

368 Given a :class:`_engine.Connection`, a string 

369 `table_name` and an optional string `schema`, return index 

370 information as a list of dictionaries with these keys: 

371 

372 * ``name`` - 

373 the index's name 

374 

375 * ``column_names`` - 

376 list of column names in order 

377 

378 * ``unique`` - 

379 boolean 

380 

381 """ 

382 

383 raise NotImplementedError() 

384 

385 def get_unique_constraints( 

386 self, connection, table_name, schema=None, **kw 

387 ): 

388 r"""Return information about unique constraints in `table_name`. 

389 

390 Given a string `table_name` and an optional string `schema`, return 

391 unique constraint information as a list of dicts with these keys: 

392 

393 * ``name`` - 

394 the unique constraint's name 

395 

396 * ``column_names`` - 

397 list of column names in order 

398 

399 * ``**kw`` - 

400 other options passed to the dialect's get_unique_constraints() 

401 method. 

402 

403 .. versionadded:: 0.9.0 

404 

405 """ 

406 

407 raise NotImplementedError() 

408 

409 def get_check_constraints(self, connection, table_name, schema=None, **kw): 

410 r"""Return information about check constraints in `table_name`. 

411 

412 Given a string `table_name` and an optional string `schema`, return 

413 check constraint information as a list of dicts with these keys: 

414 

415 * ``name`` - 

416 the check constraint's name 

417 

418 * ``sqltext`` - 

419 the check constraint's SQL expression 

420 

421 * ``**kw`` - 

422 other options passed to the dialect's get_check_constraints() 

423 method. 

424 

425 .. versionadded:: 1.1.0 

426 

427 """ 

428 

429 raise NotImplementedError() 

430 

431 def get_table_comment(self, connection, table_name, schema=None, **kw): 

432 r"""Return the "comment" for the table identified by `table_name`. 

433 

434 Given a string `table_name` and an optional string `schema`, return 

435 table comment information as a dictionary with this key: 

436 

437 text 

438 text of the comment 

439 

440 Raises ``NotImplementedError`` for dialects that don't support 

441 comments. 

442 

443 .. versionadded:: 1.2 

444 

445 """ 

446 

447 raise NotImplementedError() 

448 

449 def normalize_name(self, name): 

450 """convert the given name to lowercase if it is detected as 

451 case insensitive. 

452 

453 This method is only used if the dialect defines 

454 requires_name_normalize=True. 

455 

456 """ 

457 raise NotImplementedError() 

458 

459 def denormalize_name(self, name): 

460 """convert the given name to a case insensitive identifier 

461 for the backend if it is an all-lowercase name. 

462 

463 This method is only used if the dialect defines 

464 requires_name_normalize=True. 

465 

466 """ 

467 raise NotImplementedError() 

468 

469 def has_table(self, connection, table_name, schema=None): 

470 """Check the existence of a particular table in the database. 

471 

472 Given a :class:`_engine.Connection` object and a string 

473 `table_name`, return True if the given table (possibly within 

474 the specified `schema`) exists in the database, False 

475 otherwise. 

476 

477 """ 

478 

479 raise NotImplementedError() 

480 

481 def has_sequence(self, connection, sequence_name, schema=None): 

482 """Check the existence of a particular sequence in the database. 

483 

484 Given a :class:`_engine.Connection` object and a string 

485 `sequence_name`, return True if the given sequence exists in 

486 the database, False otherwise. 

487 

488 """ 

489 

490 raise NotImplementedError() 

491 

492 def _get_server_version_info(self, connection): 

493 """Retrieve the server version info from the given connection. 

494 

495 This is used by the default implementation to populate the 

496 "server_version_info" attribute and is called exactly 

497 once upon first connect. 

498 

499 """ 

500 

501 raise NotImplementedError() 

502 

503 def _get_default_schema_name(self, connection): 

504 """Return the string name of the currently selected schema from 

505 the given connection. 

506 

507 This is used by the default implementation to populate the 

508 "default_schema_name" attribute and is called exactly 

509 once upon first connect. 

510 

511 """ 

512 

513 raise NotImplementedError() 

514 

515 def do_begin(self, dbapi_connection): 

516 """Provide an implementation of ``connection.begin()``, given a 

517 DB-API connection. 

518 

519 The DBAPI has no dedicated "begin" method and it is expected 

520 that transactions are implicit. This hook is provided for those 

521 DBAPIs that might need additional help in this area. 

522 

523 Note that :meth:`.Dialect.do_begin` is not called unless a 

524 :class:`.Transaction` object is in use. The 

525 :meth:`.Dialect.do_autocommit` 

526 hook is provided for DBAPIs that need some extra commands emitted 

527 after a commit in order to enter the next transaction, when the 

528 SQLAlchemy :class:`_engine.Connection` 

529 is used in its default "autocommit" 

530 mode. 

531 

532 :param dbapi_connection: a DBAPI connection, typically 

533 proxied within a :class:`.ConnectionFairy`. 

534 

535 """ 

536 

537 raise NotImplementedError() 

538 

539 def do_rollback(self, dbapi_connection): 

540 """Provide an implementation of ``connection.rollback()``, given 

541 a DB-API connection. 

542 

543 :param dbapi_connection: a DBAPI connection, typically 

544 proxied within a :class:`.ConnectionFairy`. 

545 

546 """ 

547 

548 raise NotImplementedError() 

549 

550 def do_commit(self, dbapi_connection): 

551 """Provide an implementation of ``connection.commit()``, given a 

552 DB-API connection. 

553 

554 :param dbapi_connection: a DBAPI connection, typically 

555 proxied within a :class:`.ConnectionFairy`. 

556 

557 """ 

558 

559 raise NotImplementedError() 

560 

561 def do_close(self, dbapi_connection): 

562 """Provide an implementation of ``connection.close()``, given a DBAPI 

563 connection. 

564 

565 This hook is called by the :class:`_pool.Pool` 

566 when a connection has been 

567 detached from the pool, or is being returned beyond the normal 

568 capacity of the pool. 

569 

570 """ 

571 

572 raise NotImplementedError() 

573 

574 def create_xid(self): 

575 """Create a two-phase transaction ID. 

576 

577 This id will be passed to do_begin_twophase(), 

578 do_rollback_twophase(), do_commit_twophase(). Its format is 

579 unspecified. 

580 """ 

581 

582 raise NotImplementedError() 

583 

584 def do_savepoint(self, connection, name): 

585 """Create a savepoint with the given name. 

586 

587 :param connection: a :class:`_engine.Connection`. 

588 :param name: savepoint name. 

589 

590 """ 

591 

592 raise NotImplementedError() 

593 

594 def do_rollback_to_savepoint(self, connection, name): 

595 """Rollback a connection to the named savepoint. 

596 

597 :param connection: a :class:`_engine.Connection`. 

598 :param name: savepoint name. 

599 

600 """ 

601 

602 raise NotImplementedError() 

603 

604 def do_release_savepoint(self, connection, name): 

605 """Release the named savepoint on a connection. 

606 

607 :param connection: a :class:`_engine.Connection`. 

608 :param name: savepoint name. 

609 """ 

610 

611 raise NotImplementedError() 

612 

613 def do_begin_twophase(self, connection, xid): 

614 """Begin a two phase transaction on the given connection. 

615 

616 :param connection: a :class:`_engine.Connection`. 

617 :param xid: xid 

618 

619 """ 

620 

621 raise NotImplementedError() 

622 

623 def do_prepare_twophase(self, connection, xid): 

624 """Prepare a two phase transaction on the given connection. 

625 

626 :param connection: a :class:`_engine.Connection`. 

627 :param xid: xid 

628 

629 """ 

630 

631 raise NotImplementedError() 

632 

633 def do_rollback_twophase( 

634 self, connection, xid, is_prepared=True, recover=False 

635 ): 

636 """Rollback a two phase transaction on the given connection. 

637 

638 :param connection: a :class:`_engine.Connection`. 

639 :param xid: xid 

640 :param is_prepared: whether or not 

641 :meth:`.TwoPhaseTransaction.prepare` was called. 

642 :param recover: if the recover flag was passed. 

643 

644 """ 

645 

646 raise NotImplementedError() 

647 

648 def do_commit_twophase( 

649 self, connection, xid, is_prepared=True, recover=False 

650 ): 

651 """Commit a two phase transaction on the given connection. 

652 

653 

654 :param connection: a :class:`_engine.Connection`. 

655 :param xid: xid 

656 :param is_prepared: whether or not 

657 :meth:`.TwoPhaseTransaction.prepare` was called. 

658 :param recover: if the recover flag was passed. 

659 

660 """ 

661 

662 raise NotImplementedError() 

663 

664 def do_recover_twophase(self, connection): 

665 """Recover list of uncommitted prepared two phase transaction 

666 identifiers on the given connection. 

667 

668 :param connection: a :class:`_engine.Connection`. 

669 

670 """ 

671 

672 raise NotImplementedError() 

673 

674 def do_executemany(self, cursor, statement, parameters, context=None): 

675 """Provide an implementation of ``cursor.executemany(statement, 

676 parameters)``. 

677 

678 """ 

679 

680 raise NotImplementedError() 

681 

682 def do_execute(self, cursor, statement, parameters, context=None): 

683 """Provide an implementation of ``cursor.execute(statement, 

684 parameters)``. 

685 

686 """ 

687 

688 raise NotImplementedError() 

689 

690 def do_execute_no_params( 

691 self, cursor, statement, parameters, context=None 

692 ): 

693 """Provide an implementation of ``cursor.execute(statement)``. 

694 

695 The parameter collection should not be sent. 

696 

697 """ 

698 

699 raise NotImplementedError() 

700 

701 def is_disconnect(self, e, connection, cursor): 

702 """Return True if the given DB-API error indicates an invalid 

703 connection. 

704 

705 """ 

706 

707 raise NotImplementedError() 

708 

709 def connect(self, *cargs, **cparams): 

710 r"""Establish a connection using this dialect's DBAPI. 

711 

712 The default implementation of this method is:: 

713 

714 def connect(self, *cargs, **cparams): 

715 return self.dbapi.connect(*cargs, **cparams) 

716 

717 The ``*cargs, **cparams`` parameters are generated directly 

718 from this dialect's :meth:`.Dialect.create_connect_args` method. 

719 

720 This method may be used for dialects that need to perform programmatic 

721 per-connection steps when a new connection is procured from the 

722 DBAPI. 

723 

724 

725 :param \*cargs: positional parameters returned from the 

726 :meth:`.Dialect.create_connect_args` method 

727 

728 :param \*\*cparams: keyword parameters returned from the 

729 :meth:`.Dialect.create_connect_args` method. 

730 

731 :return: a DBAPI connection, typically from the :pep:`249` module 

732 level ``.connect()`` function. 

733 

734 .. seealso:: 

735 

736 :meth:`.Dialect.create_connect_args` 

737 

738 :meth:`.Dialect.on_connect` 

739 

740 """ 

741 

742 def on_connect(self): 

743 """Return a callable which sets up a newly created DBAPI connection. 

744 

745 The callable should accept a single argument "conn" which is the 

746 DBAPI connection itself. The inner callable has no 

747 return value. 

748 

749 E.g.:: 

750 

751 class MyDialect(default.DefaultDialect): 

752 # ... 

753 

754 def on_connect(self): 

755 def do_on_connect(connection): 

756 connection.execute("SET SPECIAL FLAGS etc") 

757 

758 return do_on_connect 

759 

760 This is used to set dialect-wide per-connection options such as 

761 isolation modes, Unicode modes, etc. 

762 

763 The "do_on_connect" callable is invoked by using the 

764 :meth:`_events.PoolEvents.first_connect` and 

765 :meth:`_events.PoolEvents.connect` event 

766 hooks, then unwrapping the DBAPI connection and passing it into the 

767 callable. The reason it is invoked for both events is so that any 

768 dialect-level initialization that occurs upon first connection, which 

769 also makes use of the :meth:`_events.PoolEvents.first_connect` method, 

770 will 

771 proceed after this hook has been called. This currently means the 

772 hook is in fact called twice for the very first connection in which a 

773 dialect creates; and once per connection afterwards. 

774 

775 If None is returned, no event listener is generated. 

776 

777 :return: a callable that accepts a single DBAPI connection as an 

778 argument, or None. 

779 

780 .. seealso:: 

781 

782 :meth:`.Dialect.connect` - allows the DBAPI ``connect()`` sequence 

783 itself to be controlled. 

784 

785 """ 

786 return None 

787 

788 def reset_isolation_level(self, dbapi_conn): 

789 """Given a DBAPI connection, revert its isolation to the default. 

790 

791 Note that this is a dialect-level method which is used as part 

792 of the implementation of the :class:`_engine.Connection` and 

793 :class:`_engine.Engine` 

794 isolation level facilities; these APIs should be preferred for 

795 most typical use cases. 

796 

797 .. seealso:: 

798 

799 :meth:`_engine.Connection.get_isolation_level` 

800 - view current level 

801 

802 :attr:`_engine.Connection.default_isolation_level` 

803 - view default level 

804 

805 :paramref:`.Connection.execution_options.isolation_level` - 

806 set per :class:`_engine.Connection` isolation level 

807 

808 :paramref:`_sa.create_engine.isolation_level` - 

809 set per :class:`_engine.Engine` isolation level 

810 

811 """ 

812 

813 raise NotImplementedError() 

814 

815 def set_isolation_level(self, dbapi_conn, level): 

816 """Given a DBAPI connection, set its isolation level. 

817 

818 Note that this is a dialect-level method which is used as part 

819 of the implementation of the :class:`_engine.Connection` and 

820 :class:`_engine.Engine` 

821 isolation level facilities; these APIs should be preferred for 

822 most typical use cases. 

823 

824 .. seealso:: 

825 

826 :meth:`_engine.Connection.get_isolation_level` 

827 - view current level 

828 

829 :attr:`_engine.Connection.default_isolation_level` 

830 - view default level 

831 

832 :paramref:`.Connection.execution_options.isolation_level` - 

833 set per :class:`_engine.Connection` isolation level 

834 

835 :paramref:`_sa.create_engine.isolation_level` - 

836 set per :class:`_engine.Engine` isolation level 

837 

838 """ 

839 

840 raise NotImplementedError() 

841 

842 def get_isolation_level(self, dbapi_conn): 

843 """Given a DBAPI connection, return its isolation level. 

844 

845 When working with a :class:`_engine.Connection` object, 

846 the corresponding 

847 DBAPI connection may be procured using the 

848 :attr:`_engine.Connection.connection` accessor. 

849 

850 Note that this is a dialect-level method which is used as part 

851 of the implementation of the :class:`_engine.Connection` and 

852 :class:`_engine.Engine` isolation level facilities; 

853 these APIs should be preferred for most typical use cases. 

854 

855 

856 .. seealso:: 

857 

858 :meth:`_engine.Connection.get_isolation_level` 

859 - view current level 

860 

861 :attr:`_engine.Connection.default_isolation_level` 

862 - view default level 

863 

864 :paramref:`.Connection.execution_options.isolation_level` - 

865 set per :class:`_engine.Connection` isolation level 

866 

867 :paramref:`_sa.create_engine.isolation_level` - 

868 set per :class:`_engine.Engine` isolation level 

869 

870 

871 """ 

872 

873 raise NotImplementedError() 

874 

875 def get_default_isolation_level(self, dbapi_conn): 

876 """Given a DBAPI connection, return its isolation level, or 

877 a default isolation level if one cannot be retrieved. 

878 

879 This method may only raise NotImplementedError and 

880 **must not raise any other exception**, as it is used implicitly upon 

881 first connect. 

882 

883 The method **must return a value** for a dialect that supports 

884 isolation level settings, as this level is what will be reverted 

885 towards when a per-connection isolation level change is made. 

886 

887 The method defaults to using the :meth:`.Dialect.get_isolation_level` 

888 method unless overridden by a dialect. 

889 

890 .. versionadded:: 1.3.22 

891 

892 """ 

893 raise NotImplementedError() 

894 

895 @classmethod 

896 def get_dialect_cls(cls, url): 

897 """Given a URL, return the :class:`.Dialect` that will be used. 

898 

899 This is a hook that allows an external plugin to provide functionality 

900 around an existing dialect, by allowing the plugin to be loaded 

901 from the url based on an entrypoint, and then the plugin returns 

902 the actual dialect to be used. 

903 

904 By default this just returns the cls. 

905 

906 .. versionadded:: 1.0.3 

907 

908 """ 

909 return cls 

910 

911 @classmethod 

912 def load_provisioning(cls): 

913 """Set up the provision.py module for this dialect. 

914 

915 For dialects that include a provision.py module that sets up 

916 provisioning followers, this method should initiate that process. 

917 

918 A typical implementation would be:: 

919 

920 @classmethod 

921 def load_provisioning(cls): 

922 __import__("mydialect.provision") 

923 

924 The default method assumes a module named ``provision.py`` inside 

925 the owning package of the current dialect, based on the ``__module__`` 

926 attribute:: 

927 

928 @classmethod 

929 def load_provisioning(cls): 

930 package = ".".join(cls.__module__.split(".")[0:-1]) 

931 try: 

932 __import__(package + ".provision") 

933 except ImportError: 

934 pass 

935 

936 .. versionadded:: 1.3.14 

937 

938 """ 

939 

940 @classmethod 

941 def engine_created(cls, engine): 

942 """A convenience hook called before returning the final 

943 :class:`_engine.Engine`. 

944 

945 If the dialect returned a different class from the 

946 :meth:`.get_dialect_cls` 

947 method, then the hook is called on both classes, first on 

948 the dialect class returned by the :meth:`.get_dialect_cls` method and 

949 then on the class on which the method was called. 

950 

951 The hook should be used by dialects and/or wrappers to apply special 

952 events to the engine or its components. In particular, it allows 

953 a dialect-wrapping class to apply dialect-level events. 

954 

955 .. versionadded:: 1.0.3 

956 

957 """ 

958 pass 

959 

960 

961class CreateEnginePlugin(object): 

962 """A set of hooks intended to augment the construction of an 

963 :class:`_engine.Engine` object based on entrypoint names in a URL. 

964 

965 The purpose of :class:`.CreateEnginePlugin` is to allow third-party 

966 systems to apply engine, pool and dialect level event listeners without 

967 the need for the target application to be modified; instead, the plugin 

968 names can be added to the database URL. Target applications for 

969 :class:`.CreateEnginePlugin` include: 

970 

971 * connection and SQL performance tools, e.g. which use events to track 

972 number of checkouts and/or time spent with statements 

973 

974 * connectivity plugins such as proxies 

975 

976 Plugins are registered using entry points in a similar way as that 

977 of dialects:: 

978 

979 entry_points={ 

980 'sqlalchemy.plugins': [ 

981 'myplugin = myapp.plugins:MyPlugin' 

982 ] 

983 

984 A plugin that uses the above names would be invoked from a database 

985 URL as in:: 

986 

987 from sqlalchemy import create_engine 

988 

989 engine = create_engine( 

990 "mysql+pymysql://scott:tiger@localhost/test?plugin=myplugin") 

991 

992 Alternatively, the :paramref:`.create_engine.plugins" argument may be 

993 passed as a list to :func:`_sa.create_engine`:: 

994 

995 engine = create_engine( 

996 "mysql+pymysql://scott:tiger@localhost/test", 

997 plugins=["myplugin"]) 

998 

999 .. versionadded:: 1.2.3 plugin names can also be specified 

1000 to :func:`_sa.create_engine` as a list 

1001 

1002 The ``plugin`` argument supports multiple instances, so that a URL 

1003 may specify multiple plugins; they are loaded in the order stated 

1004 in the URL:: 

1005 

1006 engine = create_engine( 

1007 "mysql+pymysql://scott:tiger@localhost/" 

1008 "test?plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three") 

1009 

1010 A plugin can receive additional arguments from the URL string as 

1011 well as from the keyword arguments passed to :func:`_sa.create_engine`. 

1012 The :class:`.URL` object and the keyword dictionary are passed to the 

1013 constructor so that these arguments can be extracted from the url's 

1014 :attr:`.URL.query` collection as well as from the dictionary:: 

1015 

1016 class MyPlugin(CreateEnginePlugin): 

1017 def __init__(self, url, kwargs): 

1018 self.my_argument_one = url.query.pop('my_argument_one') 

1019 self.my_argument_two = url.query.pop('my_argument_two') 

1020 self.my_argument_three = kwargs.pop('my_argument_three', None) 

1021 

1022 Arguments like those illustrated above would be consumed from the 

1023 following:: 

1024 

1025 from sqlalchemy import create_engine 

1026 

1027 engine = create_engine( 

1028 "mysql+pymysql://scott:tiger@localhost/" 

1029 "test?plugin=myplugin&my_argument_one=foo&my_argument_two=bar", 

1030 my_argument_three='bat') 

1031 

1032 The URL and dictionary are used for subsequent setup of the engine 

1033 as they are, so the plugin can modify their arguments in-place. 

1034 Arguments that are only understood by the plugin should be popped 

1035 or otherwise removed so that they aren't interpreted as erroneous 

1036 arguments afterwards. 

1037 

1038 When the engine creation process completes and produces the 

1039 :class:`_engine.Engine` object, it is again passed to the plugin via the 

1040 :meth:`.CreateEnginePlugin.engine_created` hook. In this hook, additional 

1041 changes can be made to the engine, most typically involving setup of 

1042 events (e.g. those defined in :ref:`core_event_toplevel`). 

1043 

1044 .. versionadded:: 1.1 

1045 

1046 """ 

1047 

1048 def __init__(self, url, kwargs): 

1049 """Construct a new :class:`.CreateEnginePlugin`. 

1050 

1051 The plugin object is instantiated individually for each call 

1052 to :func:`_sa.create_engine`. A single :class:`_engine. 

1053 Engine` will be 

1054 passed to the :meth:`.CreateEnginePlugin.engine_created` method 

1055 corresponding to this URL. 

1056 

1057 :param url: the :class:`.URL` object. The plugin should inspect 

1058 what it needs here as well as remove its custom arguments from the 

1059 :attr:`.URL.query` collection. The URL can be modified in-place 

1060 in any other way as well. 

1061 :param kwargs: The keyword arguments passed to :func:`.create_engine`. 

1062 The plugin can read and modify this dictionary in-place, to affect 

1063 the ultimate arguments used to create the engine. It should 

1064 remove its custom arguments from the dictionary as well. 

1065 

1066 """ 

1067 self.url = url 

1068 

1069 def handle_dialect_kwargs(self, dialect_cls, dialect_args): 

1070 """parse and modify dialect kwargs""" 

1071 

1072 def handle_pool_kwargs(self, pool_cls, pool_args): 

1073 """parse and modify pool kwargs""" 

1074 

1075 def engine_created(self, engine): 

1076 """Receive the :class:`_engine.Engine` 

1077 object when it is fully constructed. 

1078 

1079 The plugin may make additional changes to the engine, such as 

1080 registering engine or connection pool events. 

1081 

1082 """ 

1083 

1084 

1085class ExecutionContext(object): 

1086 """A messenger object for a Dialect that corresponds to a single 

1087 execution. 

1088 

1089 ExecutionContext should have these data members: 

1090 

1091 connection 

1092 Connection object which can be freely used by default value 

1093 generators to execute SQL. This Connection should reference the 

1094 same underlying connection/transactional resources of 

1095 root_connection. 

1096 

1097 root_connection 

1098 Connection object which is the source of this ExecutionContext. This 

1099 Connection may have close_with_result=True set, in which case it can 

1100 only be used once. 

1101 

1102 dialect 

1103 dialect which created this ExecutionContext. 

1104 

1105 cursor 

1106 DB-API cursor procured from the connection, 

1107 

1108 compiled 

1109 if passed to constructor, sqlalchemy.engine.base.Compiled object 

1110 being executed, 

1111 

1112 statement 

1113 string version of the statement to be executed. Is either 

1114 passed to the constructor, or must be created from the 

1115 sql.Compiled object by the time pre_exec() has completed. 

1116 

1117 parameters 

1118 bind parameters passed to the execute() method. For compiled 

1119 statements, this is a dictionary or list of dictionaries. For 

1120 textual statements, it should be in a format suitable for the 

1121 dialect's paramstyle (i.e. dict or list of dicts for non 

1122 positional, list or list of lists/tuples for positional). 

1123 

1124 isinsert 

1125 True if the statement is an INSERT. 

1126 

1127 isupdate 

1128 True if the statement is an UPDATE. 

1129 

1130 should_autocommit 

1131 True if the statement is a "committable" statement. 

1132 

1133 prefetch_cols 

1134 a list of Column objects for which a client-side default 

1135 was fired off. Applies to inserts and updates. 

1136 

1137 postfetch_cols 

1138 a list of Column objects for which a server-side default or 

1139 inline SQL expression value was fired off. Applies to inserts 

1140 and updates. 

1141 """ 

1142 

1143 exception = None 

1144 """A DBAPI-level exception that was caught when this ExecutionContext 

1145 attempted to execute a statement. 

1146 

1147 This attribute is meaningful only within the 

1148 :meth:`_events.ConnectionEvents.dbapi_error` event. 

1149 

1150 .. versionadded:: 0.9.7 

1151 

1152 .. seealso:: 

1153 

1154 :attr:`.ExecutionContext.is_disconnect` 

1155 

1156 :meth:`_events.ConnectionEvents.dbapi_error` 

1157 

1158 """ 

1159 

1160 is_disconnect = None 

1161 """Boolean flag set to True or False when a DBAPI-level exception 

1162 is caught when this ExecutionContext attempted to execute a statement. 

1163 

1164 This attribute is meaningful only within the 

1165 :meth:`_events.ConnectionEvents.dbapi_error` event. 

1166 

1167 .. versionadded:: 0.9.7 

1168 

1169 .. seealso:: 

1170 

1171 :attr:`.ExecutionContext.exception` 

1172 

1173 :meth:`_events.ConnectionEvents.dbapi_error` 

1174 

1175 """ 

1176 

1177 def create_cursor(self): 

1178 """Return a new cursor generated from this ExecutionContext's 

1179 connection. 

1180 

1181 Some dialects may wish to change the behavior of 

1182 connection.cursor(), such as postgresql which may return a PG 

1183 "server side" cursor. 

1184 """ 

1185 

1186 raise NotImplementedError() 

1187 

1188 def pre_exec(self): 

1189 """Called before an execution of a compiled statement. 

1190 

1191 If a compiled statement was passed to this ExecutionContext, 

1192 the `statement` and `parameters` datamembers must be 

1193 initialized after this statement is complete. 

1194 """ 

1195 

1196 raise NotImplementedError() 

1197 

1198 def post_exec(self): 

1199 """Called after the execution of a compiled statement. 

1200 

1201 If a compiled statement was passed to this ExecutionContext, 

1202 the `last_insert_ids`, `last_inserted_params`, etc. 

1203 datamembers should be available after this method completes. 

1204 """ 

1205 

1206 raise NotImplementedError() 

1207 

1208 def result(self): 

1209 """Return a result object corresponding to this ExecutionContext. 

1210 

1211 Returns a ResultProxy. 

1212 

1213 """ 

1214 

1215 raise NotImplementedError() 

1216 

1217 def handle_dbapi_exception(self, e): 

1218 """Receive a DBAPI exception which occurred upon execute, result 

1219 fetch, etc. 

1220 

1221 """ 

1222 

1223 raise NotImplementedError() 

1224 

1225 def should_autocommit_text(self, statement): 

1226 """Parse the given textual statement and return True if it refers to 

1227 a "committable" statement 

1228 

1229 """ 

1230 

1231 raise NotImplementedError() 

1232 

1233 def lastrow_has_defaults(self): 

1234 """Return True if the last INSERT or UPDATE row contained 

1235 inlined or database-side defaults. 

1236 

1237 """ 

1238 

1239 raise NotImplementedError() 

1240 

1241 def get_rowcount(self): 

1242 """Return the DBAPI ``cursor.rowcount`` value, or in some 

1243 cases an interpreted value. 

1244 

1245 See :attr:`_engine.ResultProxy.rowcount` for details on this. 

1246 

1247 """ 

1248 

1249 raise NotImplementedError() 

1250 

1251 

1252class Connectable(object): 

1253 """Interface for an object which supports execution of SQL constructs. 

1254 

1255 The two implementations of :class:`.Connectable` are 

1256 :class:`_engine.Connection` and :class:`_engine.Engine`. 

1257 

1258 Connectable must also implement the 'dialect' member which references a 

1259 :class:`.Dialect` instance. 

1260 

1261 """ 

1262 

1263 def connect(self, **kwargs): 

1264 """Return a :class:`_engine.Connection` object. 

1265 

1266 Depending on context, this may be ``self`` if this object 

1267 is already an instance of :class:`_engine.Connection`, or a newly 

1268 procured :class:`_engine.Connection` if this object is an instance 

1269 of :class:`_engine.Engine`. 

1270 

1271 """ 

1272 

1273 engine = None 

1274 """The :class:`_engine.Engine` instance referred to by this 

1275 :class:`.Connectable`. 

1276 

1277 May be ``self`` if this is already an :class:`_engine.Engine`. 

1278 

1279 """ 

1280 

1281 @util.deprecated( 

1282 "1.3", 

1283 "The :meth:`_engine.Engine.contextual_connect` and " 

1284 ":meth:`_engine.Connection.contextual_connect` methods are " 

1285 "deprecated. This " 

1286 "method is an artifact of the threadlocal engine strategy which is " 

1287 "also to be deprecated. For explicit connections from an " 

1288 ":class:`_engine.Engine`, use the :meth:`_engine.Engine.connect` " 

1289 "method.", 

1290 ) 

1291 def contextual_connect(self, *arg, **kw): 

1292 """Return a :class:`_engine.Connection` 

1293 object which may be part of an ongoing 

1294 context. 

1295 

1296 Depending on context, this may be ``self`` if this object 

1297 is already an instance of :class:`_engine.Connection`, or a newly 

1298 procured :class:`_engine.Connection` if this object is an instance 

1299 of :class:`_engine.Engine`. 

1300 

1301 """ 

1302 

1303 return self._contextual_connect(*arg, **kw) 

1304 

1305 def _contextual_connect(self): 

1306 raise NotImplementedError() 

1307 

1308 @util.deprecated( 

1309 "0.7", 

1310 "The :meth:`.Connectable.create` method is deprecated and will be " 

1311 "removed in a future release. Please use the ``.create()`` method " 

1312 "on specific schema objects to emit DDL sequences, including " 

1313 ":meth:`_schema.Table.create`, :meth:`.Index.create`, and " 

1314 ":meth:`_schema.MetaData.create_all`.", 

1315 ) 

1316 def create(self, entity, **kwargs): 

1317 """Emit CREATE statements for the given schema entity.""" 

1318 

1319 raise NotImplementedError() 

1320 

1321 @util.deprecated( 

1322 "0.7", 

1323 "The :meth:`.Connectable.drop` method is deprecated and will be " 

1324 "removed in a future release. Please use the ``.drop()`` method " 

1325 "on specific schema objects to emit DDL sequences, including " 

1326 ":meth:`_schema.Table.drop`, :meth:`.Index.drop`, and " 

1327 ":meth:`_schema.MetaData.drop_all`.", 

1328 ) 

1329 def drop(self, entity, **kwargs): 

1330 """Emit DROP statements for the given schema entity.""" 

1331 

1332 raise NotImplementedError() 

1333 

1334 def execute(self, object_, *multiparams, **params): 

1335 """Executes the given construct and returns a """ 

1336 """:class:`_engine.ResultProxy`.""" 

1337 raise NotImplementedError() 

1338 

1339 def scalar(self, object_, *multiparams, **params): 

1340 """Executes and returns the first column of the first row. 

1341 

1342 The underlying cursor is closed after execution. 

1343 """ 

1344 raise NotImplementedError() 

1345 

1346 def _run_visitor(self, visitorcallable, element, **kwargs): 

1347 raise NotImplementedError() 

1348 

1349 def _execute_clauseelement(self, elem, multiparams=None, params=None): 

1350 raise NotImplementedError() 

1351 

1352 

1353class ExceptionContext(object): 

1354 """Encapsulate information about an error condition in progress. 

1355 

1356 This object exists solely to be passed to the 

1357 :meth:`_events.ConnectionEvents.handle_error` event, 

1358 supporting an interface that 

1359 can be extended without backwards-incompatibility. 

1360 

1361 .. versionadded:: 0.9.7 

1362 

1363 """ 

1364 

1365 connection = None 

1366 """The :class:`_engine.Connection` in use during the exception. 

1367 

1368 This member is present, except in the case of a failure when 

1369 first connecting. 

1370 

1371 .. seealso:: 

1372 

1373 :attr:`.ExceptionContext.engine` 

1374 

1375 

1376 """ 

1377 

1378 engine = None 

1379 """The :class:`_engine.Engine` in use during the exception. 

1380 

1381 This member should always be present, even in the case of a failure 

1382 when first connecting. 

1383 

1384 .. versionadded:: 1.0.0 

1385 

1386 """ 

1387 

1388 cursor = None 

1389 """The DBAPI cursor object. 

1390 

1391 May be None. 

1392 

1393 """ 

1394 

1395 statement = None 

1396 """String SQL statement that was emitted directly to the DBAPI. 

1397 

1398 May be None. 

1399 

1400 """ 

1401 

1402 parameters = None 

1403 """Parameter collection that was emitted directly to the DBAPI. 

1404 

1405 May be None. 

1406 

1407 """ 

1408 

1409 original_exception = None 

1410 """The exception object which was caught. 

1411 

1412 This member is always present. 

1413 

1414 """ 

1415 

1416 sqlalchemy_exception = None 

1417 """The :class:`sqlalchemy.exc.StatementError` which wraps the original, 

1418 and will be raised if exception handling is not circumvented by the event. 

1419 

1420 May be None, as not all exception types are wrapped by SQLAlchemy. 

1421 For DBAPI-level exceptions that subclass the dbapi's Error class, this 

1422 field will always be present. 

1423 

1424 """ 

1425 

1426 chained_exception = None 

1427 """The exception that was returned by the previous handler in the 

1428 exception chain, if any. 

1429 

1430 If present, this exception will be the one ultimately raised by 

1431 SQLAlchemy unless a subsequent handler replaces it. 

1432 

1433 May be None. 

1434 

1435 """ 

1436 

1437 execution_context = None 

1438 """The :class:`.ExecutionContext` corresponding to the execution 

1439 operation in progress. 

1440 

1441 This is present for statement execution operations, but not for 

1442 operations such as transaction begin/end. It also is not present when 

1443 the exception was raised before the :class:`.ExecutionContext` 

1444 could be constructed. 

1445 

1446 Note that the :attr:`.ExceptionContext.statement` and 

1447 :attr:`.ExceptionContext.parameters` members may represent a 

1448 different value than that of the :class:`.ExecutionContext`, 

1449 potentially in the case where a 

1450 :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar 

1451 modified the statement/parameters to be sent. 

1452 

1453 May be None. 

1454 

1455 """ 

1456 

1457 is_disconnect = None 

1458 """Represent whether the exception as occurred represents a "disconnect" 

1459 condition. 

1460 

1461 This flag will always be True or False within the scope of the 

1462 :meth:`_events.ConnectionEvents.handle_error` handler. 

1463 

1464 SQLAlchemy will defer to this flag in order to determine whether or not 

1465 the connection should be invalidated subsequently. That is, by 

1466 assigning to this flag, a "disconnect" event which then results in 

1467 a connection and pool invalidation can be invoked or prevented by 

1468 changing this flag. 

1469 

1470 

1471 .. note:: The pool "pre_ping" handler enabled using the 

1472 :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not** 

1473 consult this event before deciding if the "ping" returned false, 

1474 as opposed to receiving an unhandled error. For this use case, the 

1475 :ref:`legacy recipe based on engine_connect() may be used 

1476 <pool_disconnects_pessimistic_custom>`. A future API allow more 

1477 comprehensive customization of the "disconnect" detection mechanism 

1478 across all functions. 

1479 

1480 """ 

1481 

1482 invalidate_pool_on_disconnect = True 

1483 """Represent whether all connections in the pool should be invalidated 

1484 when a "disconnect" condition is in effect. 

1485 

1486 Setting this flag to False within the scope of the 

1487 :meth:`_events.ConnectionEvents.handle_error` 

1488 event will have the effect such 

1489 that the full collection of connections in the pool will not be 

1490 invalidated during a disconnect; only the current connection that is the 

1491 subject of the error will actually be invalidated. 

1492 

1493 The purpose of this flag is for custom disconnect-handling schemes where 

1494 the invalidation of other connections in the pool is to be performed 

1495 based on other conditions, or even on a per-connection basis. 

1496 

1497 .. versionadded:: 1.0.3 

1498 

1499 """