Source code for sql_statements_test

# -*- coding: utf-8 -*-
# Copyright (C) 2017, Wolfgang Scherer, <Wolfgang.Scherer at gmx.de>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Alternatively, permisssion is granted to use this file under the
# provisions of the MIT license:
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Tests for features of :mod:`sql_statements`.

The rationale for the :mod:`sql_statements` module is documented in
:func:`test_direct_compilation`.

Other dummy functions defined for doctest provide regression rests for
:mod:`sql_statements` (they are actually duplicated there):

- :func:`test_data_types`
- :func:`test_insert_update`
- :func:`test_table_dump`

Automatic Exports
-----------------

>>> for ex in __all__: printf(sformat('from {0} import {1}', __name__, ex))
from sql_statements_test import TestTable
from sql_statements_test import TEST_TABLE_DATA
from sql_statements_test import TestTableORM

Explicit Exports
----------------

>>> if '__all_internal__' in globals():
...   for ex in __all_internal__:
...     printf(sformat('from {0} import {1}', __name__, ex))
from sql_statements_test import test_direct_compilation
from sql_statements_test import test_data_types
from sql_statements_test import test_insert_update
from sql_statements_test import test_table_dump

Test Environment
----------------

::

    import datetime
    from decimal import Decimal

    from sqlalchemy import Table, Column, Boolean, Integer, Float, Date, Time, DateTime, String, Text, Enum
    from sqlalchemy import select, insert, update

    from sqlalchemy.ext.declarative import declarative_base
    Base = declarative_base() # use common metadata

    TestTable = Table(
        'db_table', Base.metadata,
        Column('mycol', Integer(), primary_key=True),
        Column('cboolean', Boolean()),
        Column('cinteger', Integer()),
        Column('cfloat', Float()),
        Column('cdate', Date()),
        Column('ctime', Time()),
        Column('cdatetime', DateTime()),
        Column('cstring', String(50)),
        Column('ctext', Text()),
        Column('cnull', Integer()),
        Column('cenum', Enum("foo", "bar", "baz")),
    )

    TEST_TABLE_DATA = (
        5,
        1,
        10 ** 20,  # a long integer
        Decimal('3.14159'),
        datetime.date(2016, 10, 3),
        datetime.time(13, 45, 0),
        datetime.datetime(2015, 6, 24, 18, 9, 29, 42517),
        u8s('UTF-8 ' + 'snowman: ☃'),
        ucs('snowman: ☃'),
        None,
        "foo",
    )

    class TestTableORM(Base):
        __tablename__ = "db_table_orm"

        b = Column(Integer)
        c = Column(String(10))
        a = Column(Integer, primary_key=True)

Details
-------

"""

if __name__ == '__main__':
    # |:here:|
    #ve_activate_ = 've_pyramid_activate.py'
    #ve_activate_ = 've_sqlalchemy_1_0_13_activate.py'
    #ve_activate_ = 've_sqlalchemy_1_1_6_activate.py'
    #ve_activate_ = 've_sqlalchemy_1_2_9_activate.py'
    if 've_activate_' in globals():
        import os
        ve_activate = os.path.join(os.path.dirname(__file__), ve_activate_);
        if os.path.exists(ve_activate):
            globals_ = dict(globals(), __file__=ve_activate)
            exec(compile(open(ve_activate, "rb").read(), ve_activate, 'exec'), globals_)

__all__ = []
__all_internal__ = []

from compat import *
from compat import printe

from sqlalchemy import __version__
from sql_statements import COMPILE_KWARGS, LiteralDialect, sql_statement, table_dump_sql
from sqlalchemy.dialects import mysql

import datetime
from decimal import Decimal

from sqlalchemy import Table, Column
from sqlalchemy import select, insert, update

from sqlalchemy.types import (
    NullType,
    Boolean,
    BigInteger,   # inherits from Integer
    SmallInteger, # inherits from Integer
    Integer,
    Date,
    DateTime,
    Time,
    Interval,
    Float,        # inherits from Numeric
    Numeric,
    UnicodeText,  # inherits from Text
    Text,         # inherits from String
    Unicode,      # inherits from String
    Enum,         # inherits from String
    String,
    LargeBinary,  # inherits from _Binary
    _Binary,
    BINARY,       # use for _Binary
    )

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base() # use common metadata

# --------------------------------------------------
# |||:sec:||| SQL table
# --------------------------------------------------

__all__.append('TestTable')
TestTable = Table(
    'db_table', Base.metadata,
    Column('mycol', Integer(), primary_key=True),
    Column('cboolean', Boolean()),
    Column('cinteger', Integer()),
    Column('cfloat', Float()),
    Column('cdate', Date()),
    Column('ctime', Time()),
    Column('cdatetime', DateTime()),
    Column('cstring', String(50)),
    Column('ctext', Text()),
    Column('cnull', Integer(), nullable=True),
    Column('cenum', Enum("foo", "bar", "baz")),
)

__all__.append('TEST_TABLE_DATA')
TEST_TABLE_DATA = (
    5,
    1,
    10 ** 20,  # a long integer
    Decimal('3.14159'),
    datetime.date(2016, 10, 3),
    datetime.time(13, 45, 0),
    datetime.datetime(2015, 6, 24, 18, 9, 29, 42517),
    u8s('UTF-8 ' + 'snowman: ☃'),
    ucs('snowman: ☃'),
    None,
    "foo",
)

# --------------------------------------------------
# |||:sec:||| ORM table
# --------------------------------------------------

__all__.append('TestTableORM')
class TestTableORM(Base):
    __tablename__ = "db_table_orm"

    b = Column(Integer)
    c = Column(String(10))
    a = Column(Integer, primary_key=True)

# printe("# --------------------------------------------------")

# printe("# --------------------------------------------------")

COMPILE_RESULTS_BY_VERSION = dict((
    ('*', (
        # 0
        """SELECT db_table_orm.b, db_table_orm.c, db_table_orm.a
    FROM db_table_orm
    WHERE db_table_orm.a IN (%s, %s)
     LIMIT %s""",
        # 1
        "INSERT INTO db_table_orm (c, a) VALUES (%s, %s)",
        # 2
        "UPDATE db_table_orm SET c=%s WHERE db_table_orm.a = %s",
        # 3
        """SELECT db_table.mycol, db_table.cboolean, db_table.cinteger, db_table.cfloat, db_table.cdate, db_table.ctime, db_table.cdatetime, db_table.cstring, db_table.ctext, db_table.cnull, db_table.cenum
    FROM db_table
    WHERE db_table.cdate IN (%s, %s)
     LIMIT %s""",
        # 4
        "",
        # 5
        "INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext, cnull, cenum) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)",
        # 6
        "INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext, cnull, cenum) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
    )),
    ('1.0.13', [
        # 0
        """SELECT db_table_orm.b, db_table_orm.c, db_table_orm.a
    FROM db_table_orm
    WHERE db_table_orm.a IN (1, 2)
     LIMIT 1""",
        # 1
        "INSERT INTO db_table_orm (c, a) VALUES ('1', 1)",
        # 2
        "UPDATE db_table_orm SET c='2' WHERE db_table_orm.a = 1",
        # 3
        """Traceback (most recent call last):
    ...
    NotImplementedError: Don't know how to literal-quote value datetime.date(2016, 10, 3)""",
        # 4
        """Traceback (most recent call last):
    ...
    CompileError: Bind parameter 'cnull' without a renderable value not allowed here.""",
        # 5
        "INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext, cnull, cenum) VALUES (5, ..., 100000000000000000000, 3.14159, '2016-10-03', '13:45:00', '2015-06-24 18:09:29.042517', 'UTF-8 snowman: ☃', 'snowman: ☃', NULL, 'foo')",
        # 6
        """Traceback (most recent call last):
    ...
    NameError: name '_compiled' is not defined""",

    ]),
    ))
COMPILE_RESULTS_BY_VERSION['0.9.4'] = list(COMPILE_RESULTS_BY_VERSION['*'])
COMPILE_RESULTS_BY_VERSION['0.9.4'][0] = """SELECT db_table_orm.b, db_table_orm.c, db_table_orm.a
    FROM db_table_orm
    WHERE db_table_orm.a IN (1, 2)
     LIMIT %s"""
COMPILE_RESULTS_BY_VERSION['0.9.4'][3] = COMPILE_RESULTS_BY_VERSION['1.0.13'][3]
COMPILE_RESULTS_BY_VERSION['1.0.11'] = list(COMPILE_RESULTS_BY_VERSION['*'])
COMPILE_RESULTS_BY_VERSION['1.0.11'][0] = COMPILE_RESULTS_BY_VERSION['1.0.13'][0]
COMPILE_RESULTS_BY_VERSION['1.0.11'][3] = COMPILE_RESULTS_BY_VERSION['1.0.13'][3]
COMPILE_RESULTS_BY_VERSION['1.1.6'] = COMPILE_RESULTS_BY_VERSION['1.0.13']
COMPILE_RESULTS_BY_VERSION['1.2.9'] = COMPILE_RESULTS_BY_VERSION['1.1.6']

COMPILE_RESULTS = COMPILE_RESULTS_BY_VERSION.get(__version__, COMPILE_RESULTS_BY_VERSION.get('*'))

if LiteralDialect.default_paramstyle == 'format':
    COMPILE_RESULTS = [_r.replace('?', '%s') for _r in COMPILE_RESULTS]

__all_internal__.append('test_direct_compilation')
[docs]def test_direct_compilation(): pass
test_direct_compilation.__doc__ = """Direct compilation of statements. The resulting feature matrix is: +-------------+----------------+--------+---------------+----------+ | SQA version | compile_kwargs | SELECT | INSERT/UPDATE | datetime | +=============+================+========+===============+==========+ | 0.7.9 | -- | -- | -- | -- | +-------------+----------------+--------+---------------+----------+ | 0.9.4 | √ | 1/2 | -- | -- | +-------------+----------------+--------+---------------+----------+ | 1.0.11 | √ | √ | -- | -- | +-------------+----------------+--------+---------------+----------+ | 1.0.13 | √ | √ | 1/2 | -- | +-------------+----------------+--------+---------------+----------+ | 1.1.6 | √ | √ | 1/2 | -- | +-------------+----------------+--------+---------------+----------+ Support for keyword `compile_kwargs`: ======== =========================================== version compile_kwargs ======== =========================================== 0.7.9 {} 0.9.4 {'compile_kwargs': {'literal_binds': True}} 1.0.11 {'compile_kwargs': {'literal_binds': True}} 1.0.13 {'compile_kwargs': {'literal_binds': True}} 1.0.6 {'compile_kwargs': {'literal_binds': True}} ======== =========================================== .. linespacing See `Test Environment`_ for defintions. SQLAlchemy v1.0.11+ actually substitutes simple bind parameters for queries (SELECT) with any dialect: >>> from sqlalchemy.dialects import mysql >>> dialect = mysql.dialect() >>> select_stmt = select([TestTableORM.__table__]).where(TestTableORM.a.in_((1, 2, ))).limit(1) >>> printf(nts(select_stmt.compile(dialect=dialect, **COMPILE_KWARGS))) # 0 #doctest: +NORMALIZE_WHITESPACE """ + COMPILE_RESULTS[0] + """ ========== ==== ================================================== ``0.7.9`` \\- ``... WHERE db_table_orm.a IN (%s, %s) LIMIT(%s)`` ``0.9.4`` 1/2 ``... WHERE db_table_orm.a IN (1, 2) LIMIT(%s)`` ``1.0.11`` √ ``... WHERE db_table_orm.a IN (1, 2) LIMIT(1)`` ``1.0.13`` √ ``... WHERE db_table_orm.a IN (1, 2) LIMIT(1)`` ``1.1.6`` √ ``... WHERE db_table_orm.a IN (1, 2) LIMIT(1)`` ========== ==== ================================================== SQLAlchemy v1.0.13+ also substitutes simple bind parameters for INSERT and UPDATE: >>> insert_stmt = insert(TestTableORM.__table__).values(a=1, c='1') >>> printf(insert_stmt.compile(dialect=dialect, **COMPILE_KWARGS)) # 1 """ + COMPILE_RESULTS[1] + """ ========== ==== =================================================== ``0.7.9`` \\- ``INSERT INTO db_table_orm (b, a) VALUES (%s, %s)`` ``0.9.4`` \\- ``INSERT INTO db_table_orm (b, a) VALUES (%s, %s)`` ``1.0.11`` \\- ``INSERT INTO db_table_orm (b, a) VALUES (%s, %s)`` ``1.0.13`` √ ``INSERT INTO db_table_orm (c, a) VALUES ('1', 1)`` ``1.1.6`` √ ``INSERT INTO db_table_orm (c, a) VALUES ('1', 1)`` ========== ==== =================================================== >>> update_stmt = update(TestTableORM.__table__).where(TestTableORM.a == 1).values(c='2') >>> printf(update_stmt.compile(dialect=dialect, **COMPILE_KWARGS)) # 2 """ + COMPILE_RESULTS[2] + """ ========== ==== ========================================================== ``0.7.9`` \\- ``UPDATE db_table_orm SET b=%s WHERE db_table_orm.a = %s`` ``0.9.4`` \\- ``UPDATE db_table_orm SET b=%s WHERE db_table_orm.a = %s`` ``1.0.11`` \\- ``UPDATE db_table_orm SET b=%s WHERE db_table_orm.a = %s`` ``1.0.13`` √ ``UPDATE db_table_orm SET c='2' WHERE db_table_orm.a = 1`` ``1.1.6`` √ ``UPDATE db_table_orm SET c='2' WHERE db_table_orm.a = 1`` ========== ==== ========================================================== However, there is still a problem with unimplemented data types. If the parameters are substituted at all, an exception is raised: >>> select_stmt = select([TestTable]).where(TestTable.c.cdate.in_((datetime.date(2016, 10, 3), datetime.date(2015, 8, 9)))).limit(1) >>> printf(nts(select_stmt.compile(dialect=dialect, **COMPILE_KWARGS))) # 3 #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS """ + COMPILE_RESULTS[3] + """ ========== ==== ================================================== ``0.7.9`` \\- No substitution of bind params. ``0.9.4`` \\- ``NotImplementedError: Don't know how to literal-quote value datetime.date ...`` ``1.0.11`` \\- ``NotImplementedError: Don't know how to literal-quote value datetime.date ...`` ``1.0.13`` \\- ``NotImplementedError: Don't know how to literal-quote value datetime.date ...`` ``1.1.6`` \\- ``NotImplementedError: Don't know how to literal-quote value datetime.date ...`` ========== ==== ================================================== Therefore :class:`sql_statements.LiteralDialect` is still needed. >>> dialect=LiteralDialect() Unfortunately, it fails to compile INSERT statements with bind values of `None`, when using ``literal_binds=True`` for v1.0.13+. >>> insert_stmt = insert(TestTable).values(**dict(((c, v) for c, v in zip((c_.name for c_ in TestTable.c), TEST_TABLE_DATA)))) >>> _compiled=insert_stmt.compile(dialect=dialect, **COMPILE_KWARGS) # 4 #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS """ + COMPILE_RESULTS[4] + """ >>> printf(_compiled.__str__()) # 4 #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS """ + COMPILE_RESULTS[6] + """ ========== ==== ================================================== ``0.7.9`` \\- ``INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`` ``0.9.4`` \\- ``INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`` ``1.0.11`` \\- ``INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`` ``1.0.13`` \\- ``... CompileError: Bind parameter 'cnull' without a renderable value not allowed here.`` ``1.1.6`` \\- ``... CompileError: Bind parameter 'cnull' without a renderable value not allowed here.`` ========== ==== ================================================== INSERT does work for v1.0.13+, if all `None` values for the INSERT statement are replaced with :class:`sqlalchemy.null` instances: >>> from sqlalchemy import null >>> def null_if_none(value): ... if value is None: ... return null() ... return value >>> def fix_null_values(values): ... return (null_if_none(v) for v in values) >>> def fix_null_params(params): ... if issequence(params): ... # list of (col, val) tuples ... return ((c, null_if_none(v)) for c, v in params) ... return type(params)(((c, null_if_none(v)) for c, v in ditems(params))) >>> insert_stmt = insert(TestTable).values(**dict(((c, v) for c, v in zip((c_.name for c_ in TestTable.c), fix_null_values(TEST_TABLE_DATA))))) >>> _compiled = insert_stmt.compile(dialect=dialect, **COMPILE_KWARGS) >>> printf(nts(_compiled.__str__())) # 5 #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS """ + COMPILE_RESULTS[5] + """ This is just hilarious :) Example usage:: fix_null_values(TEST_TABLE_DATA) fix_null_params(zip((c_.name for c_ in TestTable.c), TEST_TABLE_DATA)) fix_null_params(dict(((c, v) for c, v in zip((c_.name for c_ in TestTable.c), TEST_TABLE_DATA)))) """ __all_internal__.append('test_data_types')
[docs]def test_data_types(): """Check correct rendering of various data types. Tested with SLQAlchemy versions: ======== =========================================== version compile_kwargs ======== =========================================== 0.7.9 {} 0.9.4 {'compile_kwargs': {'literal_binds': True}} 1.0.11 {'compile_kwargs': {'literal_binds': True}} 1.0.13 {'compile_kwargs': {'literal_binds': True}} 1.0.6 {'compile_kwargs': {'literal_binds': True}} ======== =========================================== .. linespacing See `Test Environment`_ for defintions. >>> statement = select([TestTable]).where(TestTable.c.mycol.in_(TEST_TABLE_DATA)).limit(1) >>> print(nts(sql_statement(statement))) #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS SELECT db_table.mycol, db_table.cboolean, db_table.cinteger, db_table.cfloat, db_table.cdate, db_table.ctime, db_table.cdatetime, db_table.cstring, db_table.ctext, db_table.cnull, db_table.cenum FROM db_table WHERE db_table.mycol IN (5, ..., 100000000000000000000, 3.14159, '2016-10-03', '13:45:00', '2015-06-24 18:09:29.042517', 'UTF-8 snowman: ☃', 'snowman: ☃', NULL, 'foo') LIMIT 1...; See `python - SQLAlchemy: print the actual query - Stack Overflow`_ .. _`python - SQLAlchemy: print the actual query - Stack Overflow`: http://stackoverflow.com/a/5698357/2127439 """
__all_internal__.append('test_insert_update')
[docs]def test_insert_update(): """Check correct rendering of INSERT, UPDATE. Tested with SLQAlchemy versions: ======== =========================================== version compile_kwargs ======== =========================================== 0.7.9 {} 0.9.4 {'compile_kwargs': {'literal_binds': True}} 1.0.11 {'compile_kwargs': {'literal_binds': True}} 1.0.13 {'compile_kwargs': {'literal_binds': True}} 1.0.6 {'compile_kwargs': {'literal_binds': True}} ======== =========================================== .. linespacing See `Test Environment`_ for defintions. >>> insert_stmt = insert(TestTableORM.__table__).values(a=1, b=2) >>> print(sql_statement(insert_stmt)) INSERT INTO db_table_orm (b, a) VALUES (2, 1); >>> update_stmt = update(TestTableORM.__table__).where(TestTableORM.a == 1).values(b=2) >>> print(sql_statement(update_stmt)) UPDATE db_table_orm SET b=2 WHERE db_table_orm.a = 1; See `python - Sqlalchemy - how to get raw sql from insert(), update() statements with binded params? - Stack Overflow`_. .. _`python - Sqlalchemy - how to get raw sql from insert(), update() statements with binded params? - Stack Overflow`: http://stackoverflow.com/a/42066590/2127439 """
__all_internal__.append('test_table_dump')
[docs]def test_table_dump(): """Check table dump convenience function. Tested with SLQAlchemy versions: ======== =========================================== version compile_kwargs ======== =========================================== 0.7.9 {} 0.9.4 {'compile_kwargs': {'literal_binds': True}} 1.0.11 {'compile_kwargs': {'literal_binds': True}} 1.0.13 {'compile_kwargs': {'literal_binds': True}} 1.0.6 {'compile_kwargs': {'literal_binds': True}} ======== =========================================== .. linespacing See `Test Environment`_ for defintions. **Check SQL table** >>> print(nts(table_dump_sql(TestTable, (TEST_TABLE_DATA, )))) #doctest: +ELLIPSIS CREATE TABLE db_table ( mycol INTEGER NOT NULL..., cboolean BOOL..., cinteger INTEGER, cfloat FLOAT, cdate DATE, ctime TIME, cdatetime DATETIME, cstring VARCHAR(50), ctext TEXT, cnull INTEGER, cenum..., PRIMARY KEY (mycol), CHECK (cboolean IN (0, 1))... ); INSERT INTO db_table (mycol, cboolean, cinteger, cfloat, cdate, ctime, cdatetime, cstring, ctext, cnull, cenum) VALUES (5, ..., 100000000000000000000, 3.14159, '2016-10-03', '13:45:00', '2015-06-24 18:09:29.042517', 'UTF-8 snowman: ☃', 'snowman: ☃', NULL, 'foo'); **Check ORM table** >>> print(table_dump_sql(TestTableORM, [[1, 10 ** 20, '5'], [2, 6, 'text'], [3, 9, 'done']], 'a b c'.split())) #doctest: +ELLIPSIS CREATE TABLE db_table_orm ( b INTEGER, c VARCHAR(10), a INTEGER NOT NULL..., PRIMARY KEY (a) ); INSERT INTO db_table_orm (b, c, a) VALUES (100000000000000000000, '5', 1); INSERT INTO db_table_orm (b, c, a) VALUES (6, 'text', 2); INSERT INTO db_table_orm (b, c, a) VALUES (9, 'done', 3); **Check Update on ORM table** >>> print(table_dump_sql(TestTableORM, [[1, 10 ** 20, '5'], [2, 6, 'text'], [3, 9, 'done']], 'a b c'.split(), update=True, no_create=True)) UPDATE db_table_orm SET b=100000000000000000000, c='5', a=1 WHERE db_table_orm.a = 1; UPDATE db_table_orm SET b=6, c='text', a=2 WHERE db_table_orm.a = 2; UPDATE db_table_orm SET b=9, c='done', a=3 WHERE db_table_orm.a = 3; """
if '__all_internal__' in globals(): import sys if 'sphinx.ext.autodoc' in sys.modules: __all__[:0] = __all_internal__ # __all_internal__ = list(reversed(__all_internal__)) #__all__ = list(reversed(__all__)) if __name__ == '__main__': printe(sformat(' {0:<8s} {1!s:<43s}', __version__, COMPILE_KWARGS)) if '_canonize_module_' in globals(): _canonize_module_(__name__, True) import doctest doctest.testmod() # :ide: COMPILE: Run Python3 w/o args # . (progn (save-buffer) (compile (concat "python3 ./" (file-name-nondirectory (buffer-file-name)) ""))) # :ide: COMPILE: Run w/o args # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) ""))) # :ide: +-#+ # . Compile ()