_warn_pk_with_no_anticipated_value w/ lower case table().insert() - 'ColumnSet' object has no attribute 'columns'

Issue #3842 resolved
Adam Mills created an issue

When inserting on a table without specifying the PK and with no auto generation specified in SqlAlchemy a warning is generated.

The warning code throws ColumnSet' object has no attribute 'columns'

    test = Table('test', metadata,
                   Column('id', Integer, nullable=False, primary_key=True),
                   Column('notpk', String(10), nullable=True)
                   )
    Db.session().execute(Database.test.insert().values(notpk="adam"))
  File "local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 945, in execute
    return meth(self, multiparams, params)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1046, in _execute_clauseelement
    if not self.schema_for_object.is_default else None)
  File "<string>", line 1, in <lambda>
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 436, in compile
    return self._compiler(dialect, bind=bind, **kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 442, in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py", line 435, in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py", line 216, in __init__
    self.string = self.process(self.statement, **compile_kwargs)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py", line 242, in process
    return obj._compiler_dispatch(self, **kwargs)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 81, in _compiler_dispatch
    return meth(self, **kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py", line 1968, in visit_insert
    self, insert_stmt, crud.ISINSERT, **kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/crud.py", line 57, in _setup_crud_params
    return _get_crud_params(compiler, stmt, **kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/crud.py", line 137, in _get_crud_params
    _col_bind_name, check_columns, values, kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/crud.py", line 284, in _scan_cols
    _append_param_insert_pk(compiler, stmt, c, values, kw)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/crud.py", line 467, in _append_param_insert_pk
    _warn_pk_with_no_anticipated_value(c)
  File "local/lib/python2.7/site-packages/sqlalchemy/sql/crud.py", line 684, in _warn_pk_with_no_anticipated_value
    if len(c.table.primary_key.columns) > 1:
AttributeError: 'ColumnSet' object has no attribute 'columns'

Comments (4)

  1. Mike Bayer repo owner

    hello -

    I can find a bug in this area but it does not match what you are illustrating. For a regular Table as we use in Core / ORM, and also as you appear to illustrate above, there is no bug in this warning. See test below:

    from sqlalchemy import *
    
    metadata = MetaData()
    test = Table(
        'test',
        metadata,
        Column('id', Integer, nullable=False, primary_key=True, autoincrement=False),
        Column('notpk', String(10), nullable=True)
    )
    
    e = create_engine("mysql://scott:tiger@localhost/test", echo=True)
    metadata.create_all(e)
    
    e.execute(test.insert())
    

    If you use a lower case table like this, then you get it, but that's not what you're illustrating:

    test = table(
        'test',
        Column('id', Integer, nullable=False, primary_key=True, autoincrement=False),
        Column('notpk', String(10), nullable=True)
    )
    

    that is, this is a bug that should be fixed:

    from sqlalchemy import *
    
    test = table(
        'test',
        Column('id', Integer, nullable=False, primary_key=True, autoincrement=False),
        Column('notpk', String(10), nullable=True)
    )
    print test.insert().compile(column_keys=[])
    

    but that's very minor. Can you indicate exactly how a lower-case t-table is inadvertently getting set up, if that's the case? thanks!

  2. Adam Mills reporter

    Yes, sorry I trimmed down our code to an example without testing the example... lazy. My real code actually creates views using lower-case table and its the view generating the issue.

  3. Mike Bayer repo owner

    Count columns using PrimaryKeyConstraint.len directly

    PrimaryKeyConstraint is present on Table however on table() and others it's a ColumnSet. The warning here only needs len() and PrimaryKeyConstraint supports that directly in the same way as ColumnSet.

    Change-Id: I19c11a39110bfef48cdea49a471e7ab80b537538 Fixes: #3842

    → <<cset 88ca587eae19>>

  4. Log in to comment