crud.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080
  1. # sql/crud.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. """Functions used by compiler.py to determine the parameters rendered
  8. within INSERT and UPDATE statements.
  9. """
  10. import functools
  11. import operator
  12. from . import coercions
  13. from . import dml
  14. from . import elements
  15. from . import roles
  16. from .. import exc
  17. from .. import util
  18. REQUIRED = util.symbol(
  19. "REQUIRED",
  20. """
  21. Placeholder for the value within a :class:`.BindParameter`
  22. which is required to be present when the statement is passed
  23. to :meth:`_engine.Connection.execute`.
  24. This symbol is typically used when a :func:`_expression.insert`
  25. or :func:`_expression.update` statement is compiled without parameter
  26. values present.
  27. """,
  28. )
  29. def _get_crud_params(compiler, stmt, compile_state, **kw):
  30. """create a set of tuples representing column/string pairs for use
  31. in an INSERT or UPDATE statement.
  32. Also generates the Compiled object's postfetch, prefetch, and
  33. returning column collections, used for default handling and ultimately
  34. populating the CursorResult's prefetch_cols() and postfetch_cols()
  35. collections.
  36. """
  37. compiler.postfetch = []
  38. compiler.insert_prefetch = []
  39. compiler.update_prefetch = []
  40. compiler.returning = []
  41. # getters - these are normally just column.key,
  42. # but in the case of mysql multi-table update, the rules for
  43. # .key must conditionally take tablename into account
  44. (
  45. _column_as_key,
  46. _getattr_col_key,
  47. _col_bind_name,
  48. ) = getters = _key_getters_for_crud_column(compiler, stmt, compile_state)
  49. compiler._key_getters_for_crud_column = getters
  50. # no parameters in the statement, no parameters in the
  51. # compiled params - return binds for all columns
  52. if compiler.column_keys is None and compile_state._no_parameters:
  53. return [
  54. (
  55. c,
  56. compiler.preparer.format_column(c),
  57. _create_bind_param(compiler, c, None, required=True),
  58. )
  59. for c in stmt.table.columns
  60. ]
  61. if compile_state._has_multi_parameters:
  62. spd = compile_state._multi_parameters[0]
  63. stmt_parameter_tuples = list(spd.items())
  64. elif compile_state._ordered_values:
  65. spd = compile_state._dict_parameters
  66. stmt_parameter_tuples = compile_state._ordered_values
  67. elif compile_state._dict_parameters:
  68. spd = compile_state._dict_parameters
  69. stmt_parameter_tuples = list(spd.items())
  70. else:
  71. stmt_parameter_tuples = spd = None
  72. # if we have statement parameters - set defaults in the
  73. # compiled params
  74. if compiler.column_keys is None:
  75. parameters = {}
  76. elif stmt_parameter_tuples:
  77. parameters = dict(
  78. (_column_as_key(key), REQUIRED)
  79. for key in compiler.column_keys
  80. if key not in spd
  81. )
  82. else:
  83. parameters = dict(
  84. (_column_as_key(key), REQUIRED) for key in compiler.column_keys
  85. )
  86. # create a list of column assignment clauses as tuples
  87. values = []
  88. if stmt_parameter_tuples is not None:
  89. _get_stmt_parameter_tuples_params(
  90. compiler,
  91. compile_state,
  92. parameters,
  93. stmt_parameter_tuples,
  94. _column_as_key,
  95. values,
  96. kw,
  97. )
  98. check_columns = {}
  99. # special logic that only occurs for multi-table UPDATE
  100. # statements
  101. if compile_state.isupdate and compile_state.is_multitable:
  102. _get_update_multitable_params(
  103. compiler,
  104. stmt,
  105. compile_state,
  106. stmt_parameter_tuples,
  107. check_columns,
  108. _col_bind_name,
  109. _getattr_col_key,
  110. values,
  111. kw,
  112. )
  113. if compile_state.isinsert and stmt._select_names:
  114. _scan_insert_from_select_cols(
  115. compiler,
  116. stmt,
  117. compile_state,
  118. parameters,
  119. _getattr_col_key,
  120. _column_as_key,
  121. _col_bind_name,
  122. check_columns,
  123. values,
  124. kw,
  125. )
  126. else:
  127. _scan_cols(
  128. compiler,
  129. stmt,
  130. compile_state,
  131. parameters,
  132. _getattr_col_key,
  133. _column_as_key,
  134. _col_bind_name,
  135. check_columns,
  136. values,
  137. kw,
  138. )
  139. if parameters and stmt_parameter_tuples:
  140. check = (
  141. set(parameters)
  142. .intersection(_column_as_key(k) for k, v in stmt_parameter_tuples)
  143. .difference(check_columns)
  144. )
  145. if check:
  146. raise exc.CompileError(
  147. "Unconsumed column names: %s"
  148. % (", ".join("%s" % (c,) for c in check))
  149. )
  150. if compile_state._has_multi_parameters:
  151. values = _extend_values_for_multiparams(
  152. compiler,
  153. stmt,
  154. compile_state,
  155. values,
  156. _column_as_key,
  157. kw,
  158. )
  159. elif (
  160. not values
  161. and compiler.for_executemany
  162. and compiler.dialect.supports_default_metavalue
  163. ):
  164. # convert an "INSERT DEFAULT VALUES"
  165. # into INSERT (firstcol) VALUES (DEFAULT) which can be turned
  166. # into an in-place multi values. This supports
  167. # insert_executemany_returning mode :)
  168. values = [
  169. (
  170. stmt.table.columns[0],
  171. compiler.preparer.format_column(stmt.table.columns[0]),
  172. "DEFAULT",
  173. )
  174. ]
  175. return values
  176. def _create_bind_param(
  177. compiler, col, value, process=True, required=False, name=None, **kw
  178. ):
  179. if name is None:
  180. name = col.key
  181. bindparam = elements.BindParameter(
  182. name, value, type_=col.type, required=required
  183. )
  184. bindparam._is_crud = True
  185. if process:
  186. bindparam = bindparam._compiler_dispatch(compiler, **kw)
  187. return bindparam
  188. def _handle_values_anonymous_param(compiler, col, value, name, **kw):
  189. # the insert() and update() constructs as of 1.4 will now produce anonymous
  190. # bindparam() objects in the values() collections up front when given plain
  191. # literal values. This is so that cache key behaviors, which need to
  192. # produce bound parameters in deterministic order without invoking any
  193. # compilation here, can be applied to these constructs when they include
  194. # values() (but not yet multi-values, which are not included in caching
  195. # right now).
  196. #
  197. # in order to produce the desired "crud" style name for these parameters,
  198. # which will also be targetable in engine/default.py through the usual
  199. # conventions, apply our desired name to these unique parameters by
  200. # populating the compiler truncated names cache with the desired name,
  201. # rather than having
  202. # compiler.visit_bindparam()->compiler._truncated_identifier make up a
  203. # name. Saves on call counts also.
  204. # for INSERT/UPDATE that's a CTE, we don't need names to match to
  205. # external parameters and these would also conflict in the case where
  206. # multiple insert/update are combined together using CTEs
  207. is_cte = "visiting_cte" in kw
  208. if (
  209. not is_cte
  210. and value.unique
  211. and isinstance(value.key, elements._truncated_label)
  212. ):
  213. compiler.truncated_names[("bindparam", value.key)] = name
  214. if value.type._isnull:
  215. # either unique parameter, or other bound parameters that were
  216. # passed in directly
  217. # set type to that of the column unconditionally
  218. value = value._with_binary_element_type(col.type)
  219. return value._compiler_dispatch(compiler, **kw)
  220. def _key_getters_for_crud_column(compiler, stmt, compile_state):
  221. if compile_state.isupdate and compile_state._extra_froms:
  222. # when extra tables are present, refer to the columns
  223. # in those extra tables as table-qualified, including in
  224. # dictionaries and when rendering bind param names.
  225. # the "main" table of the statement remains unqualified,
  226. # allowing the most compatibility with a non-multi-table
  227. # statement.
  228. _et = set(compile_state._extra_froms)
  229. c_key_role = functools.partial(
  230. coercions.expect_as_key, roles.DMLColumnRole
  231. )
  232. def _column_as_key(key):
  233. str_key = c_key_role(key)
  234. if hasattr(key, "table") and key.table in _et:
  235. return (key.table.name, str_key)
  236. else:
  237. return str_key
  238. def _getattr_col_key(col):
  239. if col.table in _et:
  240. return (col.table.name, col.key)
  241. else:
  242. return col.key
  243. def _col_bind_name(col):
  244. if col.table in _et:
  245. return "%s_%s" % (col.table.name, col.key)
  246. else:
  247. return col.key
  248. else:
  249. _column_as_key = functools.partial(
  250. coercions.expect_as_key, roles.DMLColumnRole
  251. )
  252. _getattr_col_key = _col_bind_name = operator.attrgetter("key")
  253. return _column_as_key, _getattr_col_key, _col_bind_name
  254. def _scan_insert_from_select_cols(
  255. compiler,
  256. stmt,
  257. compile_state,
  258. parameters,
  259. _getattr_col_key,
  260. _column_as_key,
  261. _col_bind_name,
  262. check_columns,
  263. values,
  264. kw,
  265. ):
  266. (
  267. need_pks,
  268. implicit_returning,
  269. implicit_return_defaults,
  270. postfetch_lastrowid,
  271. ) = _get_returning_modifiers(compiler, stmt, compile_state)
  272. cols = [stmt.table.c[_column_as_key(name)] for name in stmt._select_names]
  273. assert compiler.stack[-1]["selectable"] is stmt
  274. compiler.stack[-1]["insert_from_select"] = stmt.select
  275. add_select_cols = []
  276. if stmt.include_insert_from_select_defaults:
  277. col_set = set(cols)
  278. for col in stmt.table.columns:
  279. if col not in col_set and col.default:
  280. cols.append(col)
  281. for c in cols:
  282. col_key = _getattr_col_key(c)
  283. if col_key in parameters and col_key not in check_columns:
  284. parameters.pop(col_key)
  285. values.append((c, compiler.preparer.format_column(c), None))
  286. else:
  287. _append_param_insert_select_hasdefault(
  288. compiler, stmt, c, add_select_cols, kw
  289. )
  290. if add_select_cols:
  291. values.extend(add_select_cols)
  292. ins_from_select = compiler.stack[-1]["insert_from_select"]
  293. ins_from_select = ins_from_select._generate()
  294. ins_from_select._raw_columns = tuple(
  295. ins_from_select._raw_columns
  296. ) + tuple(expr for col, col_expr, expr in add_select_cols)
  297. compiler.stack[-1]["insert_from_select"] = ins_from_select
  298. def _scan_cols(
  299. compiler,
  300. stmt,
  301. compile_state,
  302. parameters,
  303. _getattr_col_key,
  304. _column_as_key,
  305. _col_bind_name,
  306. check_columns,
  307. values,
  308. kw,
  309. ):
  310. (
  311. need_pks,
  312. implicit_returning,
  313. implicit_return_defaults,
  314. postfetch_lastrowid,
  315. ) = _get_returning_modifiers(compiler, stmt, compile_state)
  316. if compile_state._parameter_ordering:
  317. parameter_ordering = [
  318. _column_as_key(key) for key in compile_state._parameter_ordering
  319. ]
  320. ordered_keys = set(parameter_ordering)
  321. cols = [
  322. stmt.table.c[key]
  323. for key in parameter_ordering
  324. if isinstance(key, util.string_types) and key in stmt.table.c
  325. ] + [c for c in stmt.table.c if c.key not in ordered_keys]
  326. else:
  327. cols = stmt.table.columns
  328. for c in cols:
  329. # scan through every column in the target table
  330. col_key = _getattr_col_key(c)
  331. if col_key in parameters and col_key not in check_columns:
  332. # parameter is present for the column. use that.
  333. _append_param_parameter(
  334. compiler,
  335. stmt,
  336. compile_state,
  337. c,
  338. col_key,
  339. parameters,
  340. _col_bind_name,
  341. implicit_returning,
  342. implicit_return_defaults,
  343. values,
  344. kw,
  345. )
  346. elif compile_state.isinsert:
  347. # no parameter is present and it's an insert.
  348. if c.primary_key and need_pks:
  349. # it's a primary key column, it will need to be generated by a
  350. # default generator of some kind, and the statement expects
  351. # inserted_primary_key to be available.
  352. if implicit_returning:
  353. # we can use RETURNING, find out how to invoke this
  354. # column and get the value where RETURNING is an option.
  355. # we can inline server-side functions in this case.
  356. _append_param_insert_pk_returning(
  357. compiler, stmt, c, values, kw
  358. )
  359. else:
  360. # otherwise, find out how to invoke this column
  361. # and get its value where RETURNING is not an option.
  362. # if we have to invoke a server-side function, we need
  363. # to pre-execute it. or if this is a straight
  364. # autoincrement column and the dialect supports it
  365. # we can use cursor.lastrowid.
  366. _append_param_insert_pk_no_returning(
  367. compiler, stmt, c, values, kw
  368. )
  369. elif c.default is not None:
  370. # column has a default, but it's not a pk column, or it is but
  371. # we don't need to get the pk back.
  372. _append_param_insert_hasdefault(
  373. compiler, stmt, c, implicit_return_defaults, values, kw
  374. )
  375. elif c.server_default is not None:
  376. # column has a DDL-level default, and is either not a pk
  377. # column or we don't need the pk.
  378. if implicit_return_defaults and c in implicit_return_defaults:
  379. compiler.returning.append(c)
  380. elif not c.primary_key:
  381. compiler.postfetch.append(c)
  382. elif implicit_return_defaults and c in implicit_return_defaults:
  383. compiler.returning.append(c)
  384. elif (
  385. c.primary_key
  386. and c is not stmt.table._autoincrement_column
  387. and not c.nullable
  388. ):
  389. _warn_pk_with_no_anticipated_value(c)
  390. elif compile_state.isupdate:
  391. # no parameter is present and it's an insert.
  392. _append_param_update(
  393. compiler,
  394. compile_state,
  395. stmt,
  396. c,
  397. implicit_return_defaults,
  398. values,
  399. kw,
  400. )
  401. def _append_param_parameter(
  402. compiler,
  403. stmt,
  404. compile_state,
  405. c,
  406. col_key,
  407. parameters,
  408. _col_bind_name,
  409. implicit_returning,
  410. implicit_return_defaults,
  411. values,
  412. kw,
  413. ):
  414. value = parameters.pop(col_key)
  415. col_value = compiler.preparer.format_column(
  416. c, use_table=compile_state.include_table_with_column_exprs
  417. )
  418. if coercions._is_literal(value):
  419. value = _create_bind_param(
  420. compiler,
  421. c,
  422. value,
  423. required=value is REQUIRED,
  424. name=_col_bind_name(c)
  425. if not compile_state._has_multi_parameters
  426. else "%s_m0" % _col_bind_name(c),
  427. **kw
  428. )
  429. elif value._is_bind_parameter:
  430. value = _handle_values_anonymous_param(
  431. compiler,
  432. c,
  433. value,
  434. name=_col_bind_name(c)
  435. if not compile_state._has_multi_parameters
  436. else "%s_m0" % _col_bind_name(c),
  437. **kw
  438. )
  439. else:
  440. # value is a SQL expression
  441. value = compiler.process(value.self_group(), **kw)
  442. if compile_state.isupdate:
  443. if implicit_return_defaults and c in implicit_return_defaults:
  444. compiler.returning.append(c)
  445. else:
  446. compiler.postfetch.append(c)
  447. else:
  448. if c.primary_key:
  449. if implicit_returning:
  450. compiler.returning.append(c)
  451. elif compiler.dialect.postfetch_lastrowid:
  452. compiler.postfetch_lastrowid = True
  453. elif implicit_return_defaults and c in implicit_return_defaults:
  454. compiler.returning.append(c)
  455. else:
  456. # postfetch specifically means, "we can SELECT the row we just
  457. # inserted by primary key to get back the server generated
  458. # defaults". so by definition this can't be used to get the
  459. # primary key value back, because we need to have it ahead of
  460. # time.
  461. compiler.postfetch.append(c)
  462. values.append((c, col_value, value))
  463. def _append_param_insert_pk_returning(compiler, stmt, c, values, kw):
  464. """Create a primary key expression in the INSERT statement where
  465. we want to populate result.inserted_primary_key and RETURNING
  466. is available.
  467. """
  468. if c.default is not None:
  469. if c.default.is_sequence:
  470. if compiler.dialect.supports_sequences and (
  471. not c.default.optional
  472. or not compiler.dialect.sequences_optional
  473. ):
  474. values.append(
  475. (
  476. c,
  477. compiler.preparer.format_column(c),
  478. compiler.process(c.default, **kw),
  479. )
  480. )
  481. compiler.returning.append(c)
  482. elif c.default.is_clause_element:
  483. values.append(
  484. (
  485. c,
  486. compiler.preparer.format_column(c),
  487. compiler.process(c.default.arg.self_group(), **kw),
  488. )
  489. )
  490. compiler.returning.append(c)
  491. else:
  492. # client side default. OK we can't use RETURNING, need to
  493. # do a "prefetch", which in fact fetches the default value
  494. # on the Python side
  495. values.append(
  496. (
  497. c,
  498. compiler.preparer.format_column(c),
  499. _create_insert_prefetch_bind_param(compiler, c, **kw),
  500. )
  501. )
  502. elif c is stmt.table._autoincrement_column or c.server_default is not None:
  503. compiler.returning.append(c)
  504. elif not c.nullable:
  505. # no .default, no .server_default, not autoincrement, we have
  506. # no indication this primary key column will have any value
  507. _warn_pk_with_no_anticipated_value(c)
  508. def _append_param_insert_pk_no_returning(compiler, stmt, c, values, kw):
  509. """Create a primary key expression in the INSERT statement where
  510. we want to populate result.inserted_primary_key and we cannot use
  511. RETURNING.
  512. Depending on the kind of default here we may create a bound parameter
  513. in the INSERT statement and pre-execute a default generation function,
  514. or we may use cursor.lastrowid if supported by the dialect.
  515. """
  516. if (
  517. # column has a Python-side default
  518. c.default is not None
  519. and (
  520. # and it either is not a sequence, or it is and we support
  521. # sequences and want to invoke it
  522. not c.default.is_sequence
  523. or (
  524. compiler.dialect.supports_sequences
  525. and (
  526. not c.default.optional
  527. or not compiler.dialect.sequences_optional
  528. )
  529. )
  530. )
  531. ) or (
  532. # column is the "autoincrement column"
  533. c is stmt.table._autoincrement_column
  534. and (
  535. # dialect can't use cursor.lastrowid
  536. not compiler.dialect.postfetch_lastrowid
  537. and (
  538. # column has a Sequence and we support those
  539. (
  540. c.default is not None
  541. and c.default.is_sequence
  542. and compiler.dialect.supports_sequences
  543. )
  544. or
  545. # column has no default on it, but dialect can run the
  546. # "autoincrement" mechanism explicitly, e.g. PostgreSQL
  547. # SERIAL we know the sequence name
  548. (
  549. c.default is None
  550. and compiler.dialect.preexecute_autoincrement_sequences
  551. )
  552. )
  553. )
  554. ):
  555. # do a pre-execute of the default
  556. values.append(
  557. (
  558. c,
  559. compiler.preparer.format_column(c),
  560. _create_insert_prefetch_bind_param(compiler, c, **kw),
  561. )
  562. )
  563. elif (
  564. c.default is None
  565. and c.server_default is None
  566. and not c.nullable
  567. and c is not stmt.table._autoincrement_column
  568. ):
  569. # no .default, no .server_default, not autoincrement, we have
  570. # no indication this primary key column will have any value
  571. _warn_pk_with_no_anticipated_value(c)
  572. elif compiler.dialect.postfetch_lastrowid:
  573. # finally, where it seems like there will be a generated primary key
  574. # value and we haven't set up any other way to fetch it, and the
  575. # dialect supports cursor.lastrowid, switch on the lastrowid flag so
  576. # that the DefaultExecutionContext calls upon cursor.lastrowid
  577. compiler.postfetch_lastrowid = True
  578. def _append_param_insert_hasdefault(
  579. compiler, stmt, c, implicit_return_defaults, values, kw
  580. ):
  581. if c.default.is_sequence:
  582. if compiler.dialect.supports_sequences and (
  583. not c.default.optional or not compiler.dialect.sequences_optional
  584. ):
  585. values.append(
  586. (
  587. c,
  588. compiler.preparer.format_column(c),
  589. compiler.process(c.default, **kw),
  590. )
  591. )
  592. if implicit_return_defaults and c in implicit_return_defaults:
  593. compiler.returning.append(c)
  594. elif not c.primary_key:
  595. compiler.postfetch.append(c)
  596. elif c.default.is_clause_element:
  597. values.append(
  598. (
  599. c,
  600. compiler.preparer.format_column(c),
  601. compiler.process(c.default.arg.self_group(), **kw),
  602. )
  603. )
  604. if implicit_return_defaults and c in implicit_return_defaults:
  605. compiler.returning.append(c)
  606. elif not c.primary_key:
  607. # don't add primary key column to postfetch
  608. compiler.postfetch.append(c)
  609. else:
  610. values.append(
  611. (
  612. c,
  613. compiler.preparer.format_column(c),
  614. _create_insert_prefetch_bind_param(compiler, c, **kw),
  615. )
  616. )
  617. def _append_param_insert_select_hasdefault(compiler, stmt, c, values, kw):
  618. if c.default.is_sequence:
  619. if compiler.dialect.supports_sequences and (
  620. not c.default.optional or not compiler.dialect.sequences_optional
  621. ):
  622. values.append(
  623. (c, compiler.preparer.format_column(c), c.default.next_value())
  624. )
  625. elif c.default.is_clause_element:
  626. values.append(
  627. (c, compiler.preparer.format_column(c), c.default.arg.self_group())
  628. )
  629. else:
  630. values.append(
  631. (
  632. c,
  633. compiler.preparer.format_column(c),
  634. _create_insert_prefetch_bind_param(
  635. compiler, c, process=False, **kw
  636. ),
  637. )
  638. )
  639. def _append_param_update(
  640. compiler, compile_state, stmt, c, implicit_return_defaults, values, kw
  641. ):
  642. include_table = compile_state.include_table_with_column_exprs
  643. if c.onupdate is not None and not c.onupdate.is_sequence:
  644. if c.onupdate.is_clause_element:
  645. values.append(
  646. (
  647. c,
  648. compiler.preparer.format_column(
  649. c,
  650. use_table=include_table,
  651. ),
  652. compiler.process(c.onupdate.arg.self_group(), **kw),
  653. )
  654. )
  655. if implicit_return_defaults and c in implicit_return_defaults:
  656. compiler.returning.append(c)
  657. else:
  658. compiler.postfetch.append(c)
  659. else:
  660. values.append(
  661. (
  662. c,
  663. compiler.preparer.format_column(
  664. c,
  665. use_table=include_table,
  666. ),
  667. _create_update_prefetch_bind_param(compiler, c, **kw),
  668. )
  669. )
  670. elif c.server_onupdate is not None:
  671. if implicit_return_defaults and c in implicit_return_defaults:
  672. compiler.returning.append(c)
  673. else:
  674. compiler.postfetch.append(c)
  675. elif (
  676. implicit_return_defaults
  677. and (stmt._return_defaults_columns or not stmt._return_defaults)
  678. and c in implicit_return_defaults
  679. ):
  680. compiler.returning.append(c)
  681. def _create_insert_prefetch_bind_param(
  682. compiler, c, process=True, name=None, **kw
  683. ):
  684. param = _create_bind_param(
  685. compiler, c, None, process=process, name=name, **kw
  686. )
  687. compiler.insert_prefetch.append(c)
  688. return param
  689. def _create_update_prefetch_bind_param(
  690. compiler, c, process=True, name=None, **kw
  691. ):
  692. param = _create_bind_param(
  693. compiler, c, None, process=process, name=name, **kw
  694. )
  695. compiler.update_prefetch.append(c)
  696. return param
  697. class _multiparam_column(elements.ColumnElement):
  698. _is_multiparam_column = True
  699. def __init__(self, original, index):
  700. self.index = index
  701. self.key = "%s_m%d" % (original.key, index + 1)
  702. self.original = original
  703. self.default = original.default
  704. self.type = original.type
  705. def compare(self, other, **kw):
  706. raise NotImplementedError()
  707. def _copy_internals(self, other, **kw):
  708. raise NotImplementedError()
  709. def __eq__(self, other):
  710. return (
  711. isinstance(other, _multiparam_column)
  712. and other.key == self.key
  713. and other.original == self.original
  714. )
  715. def _process_multiparam_default_bind(compiler, stmt, c, index, kw):
  716. if not c.default:
  717. raise exc.CompileError(
  718. "INSERT value for column %s is explicitly rendered as a bound"
  719. "parameter in the VALUES clause; "
  720. "a Python-side value or SQL expression is required" % c
  721. )
  722. elif c.default.is_clause_element:
  723. return compiler.process(c.default.arg.self_group(), **kw)
  724. elif c.default.is_sequence:
  725. # these conditions would have been established
  726. # by append_param_insert_(?:hasdefault|pk_returning|pk_no_returning)
  727. # in order for us to be here, so these don't need to be
  728. # checked
  729. # assert compiler.dialect.supports_sequences and (
  730. # not c.default.optional
  731. # or not compiler.dialect.sequences_optional
  732. # )
  733. return compiler.process(c.default, **kw)
  734. else:
  735. col = _multiparam_column(c, index)
  736. if isinstance(stmt, dml.Insert):
  737. return _create_insert_prefetch_bind_param(compiler, col, **kw)
  738. else:
  739. return _create_update_prefetch_bind_param(compiler, col, **kw)
  740. def _get_update_multitable_params(
  741. compiler,
  742. stmt,
  743. compile_state,
  744. stmt_parameter_tuples,
  745. check_columns,
  746. _col_bind_name,
  747. _getattr_col_key,
  748. values,
  749. kw,
  750. ):
  751. normalized_params = dict(
  752. (coercions.expect(roles.DMLColumnRole, c), param)
  753. for c, param in stmt_parameter_tuples
  754. )
  755. include_table = compile_state.include_table_with_column_exprs
  756. affected_tables = set()
  757. for t in compile_state._extra_froms:
  758. for c in t.c:
  759. if c in normalized_params:
  760. affected_tables.add(t)
  761. check_columns[_getattr_col_key(c)] = c
  762. value = normalized_params[c]
  763. col_value = compiler.process(c, include_table=include_table)
  764. if coercions._is_literal(value):
  765. value = _create_bind_param(
  766. compiler,
  767. c,
  768. value,
  769. required=value is REQUIRED,
  770. name=_col_bind_name(c),
  771. **kw # TODO: no test coverage for literal binds here
  772. )
  773. elif value._is_bind_parameter:
  774. value = _handle_values_anonymous_param(
  775. compiler, c, value, name=_col_bind_name(c), **kw
  776. )
  777. else:
  778. compiler.postfetch.append(c)
  779. value = compiler.process(value.self_group(), **kw)
  780. values.append((c, col_value, value))
  781. # determine tables which are actually to be updated - process onupdate
  782. # and server_onupdate for these
  783. for t in affected_tables:
  784. for c in t.c:
  785. if c in normalized_params:
  786. continue
  787. elif c.onupdate is not None and not c.onupdate.is_sequence:
  788. if c.onupdate.is_clause_element:
  789. values.append(
  790. (
  791. c,
  792. compiler.process(c, include_table=include_table),
  793. compiler.process(
  794. c.onupdate.arg.self_group(), **kw
  795. ),
  796. )
  797. )
  798. compiler.postfetch.append(c)
  799. else:
  800. values.append(
  801. (
  802. c,
  803. compiler.process(c, include_table=include_table),
  804. _create_update_prefetch_bind_param(
  805. compiler, c, name=_col_bind_name(c), **kw
  806. ),
  807. )
  808. )
  809. elif c.server_onupdate is not None:
  810. compiler.postfetch.append(c)
  811. def _extend_values_for_multiparams(
  812. compiler,
  813. stmt,
  814. compile_state,
  815. values,
  816. _column_as_key,
  817. kw,
  818. ):
  819. values_0 = values
  820. values = [values]
  821. for i, row in enumerate(compile_state._multi_parameters[1:]):
  822. extension = []
  823. row = {_column_as_key(key): v for key, v in row.items()}
  824. for (col, col_expr, param) in values_0:
  825. if col.key in row:
  826. key = col.key
  827. if coercions._is_literal(row[key]):
  828. new_param = _create_bind_param(
  829. compiler,
  830. col,
  831. row[key],
  832. name="%s_m%d" % (col.key, i + 1),
  833. **kw
  834. )
  835. else:
  836. new_param = compiler.process(row[key].self_group(), **kw)
  837. else:
  838. new_param = _process_multiparam_default_bind(
  839. compiler, stmt, col, i, kw
  840. )
  841. extension.append((col, col_expr, new_param))
  842. values.append(extension)
  843. return values
  844. def _get_stmt_parameter_tuples_params(
  845. compiler,
  846. compile_state,
  847. parameters,
  848. stmt_parameter_tuples,
  849. _column_as_key,
  850. values,
  851. kw,
  852. ):
  853. for k, v in stmt_parameter_tuples:
  854. colkey = _column_as_key(k)
  855. if colkey is not None:
  856. parameters.setdefault(colkey, v)
  857. else:
  858. # a non-Column expression on the left side;
  859. # add it to values() in an "as-is" state,
  860. # coercing right side to bound param
  861. # note one of the main use cases for this is array slice
  862. # updates on PostgreSQL, as the left side is also an expression.
  863. col_expr = compiler.process(
  864. k, include_table=compile_state.include_table_with_column_exprs
  865. )
  866. if coercions._is_literal(v):
  867. v = compiler.process(
  868. elements.BindParameter(None, v, type_=k.type), **kw
  869. )
  870. else:
  871. if v._is_bind_parameter and v.type._isnull:
  872. # either unique parameter, or other bound parameters that
  873. # were passed in directly
  874. # set type to that of the column unconditionally
  875. v = v._with_binary_element_type(k.type)
  876. v = compiler.process(v.self_group(), **kw)
  877. values.append((k, col_expr, v))
  878. def _get_returning_modifiers(compiler, stmt, compile_state):
  879. need_pks = (
  880. compile_state.isinsert
  881. and not stmt._inline
  882. and (
  883. not compiler.for_executemany
  884. or (
  885. compiler.dialect.insert_executemany_returning
  886. and stmt._return_defaults
  887. )
  888. )
  889. and not stmt._returning
  890. and not compile_state._has_multi_parameters
  891. )
  892. implicit_returning = (
  893. need_pks
  894. and compiler.dialect.implicit_returning
  895. and stmt.table.implicit_returning
  896. )
  897. if compile_state.isinsert:
  898. implicit_return_defaults = implicit_returning and stmt._return_defaults
  899. elif compile_state.isupdate:
  900. implicit_return_defaults = (
  901. compiler.dialect.implicit_returning
  902. and stmt.table.implicit_returning
  903. and stmt._return_defaults
  904. )
  905. else:
  906. # this line is unused, currently we are always
  907. # isinsert or isupdate
  908. implicit_return_defaults = False # pragma: no cover
  909. if implicit_return_defaults:
  910. if not stmt._return_defaults_columns:
  911. implicit_return_defaults = set(stmt.table.c)
  912. else:
  913. implicit_return_defaults = set(stmt._return_defaults_columns)
  914. postfetch_lastrowid = need_pks and compiler.dialect.postfetch_lastrowid
  915. return (
  916. need_pks,
  917. implicit_returning,
  918. implicit_return_defaults,
  919. postfetch_lastrowid,
  920. )
  921. def _warn_pk_with_no_anticipated_value(c):
  922. msg = (
  923. "Column '%s.%s' is marked as a member of the "
  924. "primary key for table '%s', "
  925. "but has no Python-side or server-side default generator indicated, "
  926. "nor does it indicate 'autoincrement=True' or 'nullable=True', "
  927. "and no explicit value is passed. "
  928. "Primary key columns typically may not store NULL."
  929. % (c.table.fullname, c.name, c.table.fullname)
  930. )
  931. if len(c.table.primary_key) > 1:
  932. msg += (
  933. " Note that as of SQLAlchemy 1.1, 'autoincrement=True' must be "
  934. "indicated explicitly for composite (e.g. multicolumn) primary "
  935. "keys if AUTO_INCREMENT/SERIAL/IDENTITY "
  936. "behavior is expected for one of the columns in the primary key. "
  937. "CREATE TABLE statements are impacted by this change as well on "
  938. "most backends."
  939. )
  940. util.warn(msg)