从DictRow中删除项目

时间:2015-12-31 19:27:42

标签: python postgresql psycopg2

是否有一种从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删除项目的建议吗?

3 个答案:

答案 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)

使用RealDictCursor

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}