是否有一种从psycopg2
DictRow
对象中删除项目(其值和索引)的简洁方法?
我使用psycopg2
与两个不同的postgresql数据库进行交互。我想将一条记录作为DictRow从一个数据库复制到另一个数据库 - 和我想在插入之前从记录中删除几个字段。
例如,如果我有一个名为row
的DictRow:
>>> print row
[12, '2015-12-31', 'kefir sriracha put a bird on it']
>>> print row.keys()
['id', 'created_at', 'output_example']
使用row.pop(INDEX)
更改列表的索引,因此存储在row._index
属性中的密钥不再正确!
>>> row.pop(0)
12
>>> print row
['2015-12-31', 'kefir sriracha put a bird on it']
>>> print row.keys()
['id', 'created_at', 'output_example']
>>> print row['id']
'2015-12-31' # GAAAAA!!!
您无法使用del row['id']
:TypeError
。我认为这是因为底层对象是list
并且期望整数索引。
我目前的解决方法是做一些这样的事情,这似乎是不优雅的:
fields = [f for f in row.keys() if f != 'id']
values = [v for k, v in row.iteritems() if k != 'id']
有关更直接地从DictRow删除项目的建议吗?
答案 0 :(得分:1)
我一直在使用的解决方案是取DictRow
并将其转换为dict
。
my_row = dict(row.items())
del my_row['id']
fields = my_row.keys()
values = my_row.values()
它确实改变了数据类型,因此对我提出的问题不是一个很好的答案。在这种特定情况下,它比重构依赖于相同游标及其行为的其他代码更容易。
答案 1 :(得分:1)
示例:(在psycopg2 == 2.8.4,python 3.7下)
(您可能已经解决了这个问题,但是我在发布,以防其他人需要。)
# We want to exclude column 'a' in row.
row: DictRow
# row = {'a': value1, 'b': value2}
# row._index = OrderedDict({'a': 0, 'b': 1})
remove_columns = ['a']
remove_columns_index_set = set()
# Find the index of the column to exclude. a -> 0.
for col in remove_columns:
remove_columns_index_set.add(row._index.get(col))
# Override the list with new values. (I find this line in DictRow's __init__)
row[:] = [col for idx, col in enumerate(row) if idx not in remove_columns_index_set]
# Delete the index of removed column.
# Because _index in row is shared among all rows, we only need to update it once.
for remove_col in remove_columns:
del row._index[remove_col]
# Update the DictRow index to new value.
for idx, column in enumerate(row._index):
row._index[column] = idx
我一直在寻找相同的问题。
有在我的代码库中包括并重写DictRow的冲动:)
答案 2 :(得分:0)
cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
query = """select 1 as one, 2 as two"""
cursor.execute(query)
rs = cursor.fetchall()
d = rs[0]
print d
del(d['one'])
print d
输出:
{'two': 2, 'one': 1}
{'two': 2}