使用SQLAlchemy对Postgres执行upsert时发生CompileError

时间:2018-12-19 10:17:35

标签: python postgresql pandas sqlalchemy

我有一个数据库,其中有一个名为blob_nlp的表。该表的索引是一个名为twid的外键字段。

  column_name         data_type
0        twid  double precision
1     user_id  double precision
2  is_retweet           boolean
3        bpol  double precision
4       bsubj  double precision
5         bnp              text

twid字段外,该表为空。我想用DataFrame中的值填充这些空字段。

但是,当我尝试将outputdf数据框中的行插入PostGres时,SQLAlchemy会引发CompileError。我在做什么错了?

这是我的代码中不起作用的部分。

engine = create_engine('postgresql+psycopg2://{user}:{password}@{hostip}/{db}'.format(**dbkeys))

# Get metadata objects for tables in database
metadata = MetaData(engine, reflect=True)
tweets = metadata.tables['tweets']
authinfo = metadata.tables['authinfo']
twerrors = metadata.tables['twerrors']

for index, row in outputdf.iterrows():
    query = """INSERT INTO blob_nlp (twid, bpol, bsubj, bnp) VALUES (%s, %s, %s, %s);"""
    data = (row.twid, row.bpol, row.bsubj, row.bnp)
    engine.execute(query, data)  

    inserttw = insert(tweets).values(twid = row.twid, user_id = row.user_id, is_retweet = row.is_retweet, bpol = row.bpol, bsubj=row.bsubj, bnp=row.bnp)

    # If there the record is already in the database, update existing fields (upsert).
    upsert1 = inserttw.on_conflict_do_update(index_elements=['twid'], set_={'twid': row.twid, 'user_id' : row.user_id, 
                                                                            'is_retweet': row.is_retweet, 'bpol': row.bpol, 
                                                                            'bsubj': row.bsubj, 'bnp': row.bnp})

错误:

---------------------------------------------------------------------------
CompileError                              Traceback (most recent call last)
<ipython-input-38-2cc7fceca8e0> in <module>
     95                                                                                 'bsubj': row.bsubj, 'bnp': row.bnp})
     96 
---> 97         engine.execute(upsert1)
     98 
     99 

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/engine/base.py in execute(self, statement, *multiparams, **params)
   2073 
   2074         connection = self.contextual_connect(close_with_result=True)
-> 2075         return connection.execute(statement, *multiparams, **params)
   2076 
   2077     def scalar(self, statement, *multiparams, **params):

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/engine/base.py in execute(self, object, *multiparams, **params)
    946             raise exc.ObjectNotExecutableError(object)
    947         else:
--> 948             return meth(self, multiparams, params)
    949 
    950     def _execute_function(self, func, multiparams, params):

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/elements.py in _execute_on_connection(self, connection, multiparams, params)
    267     def _execute_on_connection(self, connection, multiparams, params):
    268         if self.supports_execution:
--> 269             return connection._execute_clauseelement(self, multiparams, params)
    270         else:
    271             raise exc.ObjectNotExecutableError(self)

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/engine/base.py in _execute_clauseelement(self, elem, multiparams, params)
   1051                 inline=len(distilled_params) > 1,
   1052                 schema_translate_map=self.schema_for_object
-> 1053                 if not self.schema_for_object.is_default else None)
   1054 
   1055         ret = self._execute_context(

<string> in <lambda>(self, bind, dialect, **kw)

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/elements.py in compile(self, default, bind, dialect, **kw)
    440             else:
    441                 dialect = default.StrCompileDialect()
--> 442         return self._compiler(dialect, bind=bind, **kw)
    443 
    444     def _compiler(self, dialect, **kw):

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/elements.py in _compiler(self, dialect, **kw)
    446         Dialect."""
    447 
--> 448         return dialect.statement_compiler(dialect, self, **kw)
    449 
    450     def __str__(self):

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/compiler.py in __init__(self, dialect, statement, column_keys, inline, **kwargs)
    451         # dialect.label_length or dialect.max_identifier_length
    452         self.truncated_names = {}
--> 453         Compiled.__init__(self, dialect, statement, **kwargs)
    454 
    455         if (

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/compiler.py in __init__(self, dialect, statement, bind, schema_translate_map, compile_kwargs)
    217             if self.can_execute:
    218                 self.execution_options = statement._execution_options
--> 219             self.string = self.process(self.statement, **compile_kwargs)
    220 
    221     @util.deprecated("0.7", ":class:`.Compiled` objects now compile "

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/compiler.py in process(self, obj, **kwargs)
    243 
    244     def process(self, obj, **kwargs):
--> 245         return obj._compiler_dispatch(self, **kwargs)
    246 
    247     def __str__(self):

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/visitors.py in _compiler_dispatch(self, visitor, **kw)
     79                     raise exc.UnsupportedCompilationError(visitor, cls)
     80                 else:
---> 81                     return meth(self, **kw)
     82         else:
     83             # The optimization opportunity is lost for this case because the

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/compiler.py in visit_insert(self, insert_stmt, asfrom, **kw)
   2057 
   2058         crud_params = crud._setup_crud_params(
-> 2059             self, insert_stmt, crud.ISINSERT, **kw)
   2060 
   2061         if not crud_params and \

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/crud.py in _setup_crud_params(compiler, stmt, local_stmt_type, **kw)
     55     try:
     56         if local_stmt_type in (ISINSERT, ISUPDATE):
---> 57             return _get_crud_params(compiler, stmt, **kw)
     58     finally:
     59         if should_restore:

~/anaconda3/lib/python3.6/site-packages/sqlalchemy/sql/crud.py in _get_crud_params(compiler, stmt, **kw)
    144             raise exc.CompileError(
    145                 "Unconsumed column names: %s" %
--> 146                 (", ".join("%s" % c for c in check))
    147             )
    148 

CompileError: Unconsumed column names: bsubj, bpol, bnp

0 个答案:

没有答案