python : sqlalchemy 批量插入 on_conflict_update
python : sqlalchemy batch insert with on_conflict_update
我必须插入大约。我的 postgres 数据库每天 30000 行,
我的数据库中有 4 列,即:
id(pkey)、类别、创建日期、更新时间。
我的要求是用今天的日期和新类别更新 updatedon 和类别列(如果 id 存在),否则 插入一个新行,createddate 和 updateon 相同.
我找到了 Ilja Everilä 的 [answer]: 进行批量更新
insert_statement = sqlalchemy.dialects.postgresql.insert(id_tag)
upsert_statement = insert_statement.on_conflict_do_update(
constraint='id',
set_={ "createddate": insert_statement.excluded.createddate }
)
insert_values = df.to_dict(orient='records')
conn.execute(upsert_statement, insert_values)
它抛出 AttributeError,
Traceback (most recent call last):
File "<ipython-input-60-4c5e5e0daf14>", line 5, in <module>
set_= dict(createddate = insert_statement.excluded.createddate)
File "/home/bluepi/anaconda2/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 764, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/bluepi/anaconda2/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/dml.py", line 43, in excluded
return alias(self.table, name='excluded').columns
File "/home/bluepi/anaconda2/lib/python2.7/site-packages/sqlalchemy/sql/selectable.py", line 161, in alias
return _interpret_as_from(selectable).alias(name=name, flat=flat)
AttributeError: 'TextClause' object has no attribute 'alias'
我已经按照此处所示尝试了一项一项的更新 http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#postgresql-insert-on-conflict,但我遇到了同样的错误。
请帮助我了解哪里出了问题,在此先感谢。
来自您的评论
id_tag is nothing but mane of my table in postgres
可以推断出 id_tag
绑定到一个字符串。如果您提供的 Minimal, Complete, and Verifiable example, there'd been a lot less guesswork. As it turns out, postgresql.dml.insert()
automatically wraps passed strings in a text()
construct, and the result when trying to use Insert.excluded
是:
In [2]: postgresql.insert('fail').excluded
~/sqlalchemy/lib/sqlalchemy/sql/selectable.py:43: SAWarning: Textual SQL FROM expression 'fail' should be explicitly declared as text('fail'), or use table('fail') for more specificity (this warning may be suppressed after 10 occurrences)
{"expr": util.ellipses_string(element)})
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-f176aac8b913> in <module>()
----> 1 postgresql.insert('fail').excluded
~/sqlalchemy/lib/sqlalchemy/util/langhelpers.py in __get__(self, obj, cls)
765 if obj is None:
766 return self
--> 767 obj.__dict__[self.__name__] = result = self.fget(obj)
768 return result
769
~/sqlalchemy/lib/sqlalchemy/dialects/postgresql/dml.py in excluded(self)
41
42 """
---> 43 return alias(self.table, name='excluded').columns
44
45 @_generative
~/sqlalchemy/lib/sqlalchemy/sql/selectable.py in alias(selectable, name, flat)
159
160 """
--> 161 return _interpret_as_from(selectable).alias(name=name, flat=flat)
162
163
AttributeError: 'TextClause' object has no attribute 'alias'
因此,与其将包含 table 名称的字符串传递给 postgresql.dml.insert()
,不如将其传递给实际的 Table
object, or a light weight table()
construct that has been populated with column()
对象。
我必须插入大约。我的 postgres 数据库每天 30000 行, 我的数据库中有 4 列,即: id(pkey)、类别、创建日期、更新时间。 我的要求是用今天的日期和新类别更新 updatedon 和类别列(如果 id 存在),否则 插入一个新行,createddate 和 updateon 相同.
我找到了 Ilja Everilä 的 [answer]:
insert_statement = sqlalchemy.dialects.postgresql.insert(id_tag)
upsert_statement = insert_statement.on_conflict_do_update(
constraint='id',
set_={ "createddate": insert_statement.excluded.createddate }
)
insert_values = df.to_dict(orient='records')
conn.execute(upsert_statement, insert_values)
它抛出 AttributeError,
Traceback (most recent call last):
File "<ipython-input-60-4c5e5e0daf14>", line 5, in <module>
set_= dict(createddate = insert_statement.excluded.createddate)
File "/home/bluepi/anaconda2/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 764, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/bluepi/anaconda2/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/dml.py", line 43, in excluded
return alias(self.table, name='excluded').columns
File "/home/bluepi/anaconda2/lib/python2.7/site-packages/sqlalchemy/sql/selectable.py", line 161, in alias
return _interpret_as_from(selectable).alias(name=name, flat=flat)
AttributeError: 'TextClause' object has no attribute 'alias'
我已经按照此处所示尝试了一项一项的更新 http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#postgresql-insert-on-conflict,但我遇到了同样的错误。
请帮助我了解哪里出了问题,在此先感谢。
来自您的评论
id_tag is nothing but mane of my table in postgres
可以推断出 id_tag
绑定到一个字符串。如果您提供的 Minimal, Complete, and Verifiable example, there'd been a lot less guesswork. As it turns out, postgresql.dml.insert()
automatically wraps passed strings in a text()
construct, and the result when trying to use Insert.excluded
是:
In [2]: postgresql.insert('fail').excluded
~/sqlalchemy/lib/sqlalchemy/sql/selectable.py:43: SAWarning: Textual SQL FROM expression 'fail' should be explicitly declared as text('fail'), or use table('fail') for more specificity (this warning may be suppressed after 10 occurrences)
{"expr": util.ellipses_string(element)})
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-f176aac8b913> in <module>()
----> 1 postgresql.insert('fail').excluded
~/sqlalchemy/lib/sqlalchemy/util/langhelpers.py in __get__(self, obj, cls)
765 if obj is None:
766 return self
--> 767 obj.__dict__[self.__name__] = result = self.fget(obj)
768 return result
769
~/sqlalchemy/lib/sqlalchemy/dialects/postgresql/dml.py in excluded(self)
41
42 """
---> 43 return alias(self.table, name='excluded').columns
44
45 @_generative
~/sqlalchemy/lib/sqlalchemy/sql/selectable.py in alias(selectable, name, flat)
159
160 """
--> 161 return _interpret_as_from(selectable).alias(name=name, flat=flat)
162
163
AttributeError: 'TextClause' object has no attribute 'alias'
因此,与其将包含 table 名称的字符串传递给 postgresql.dml.insert()
,不如将其传递给实际的 Table
object, or a light weight table()
construct that has been populated with column()
对象。