如何在 For 循环中的字典中插入数据

How to insert data in a dictionary inside a For-loop

我卡在这部分了。我正在使用 PRAW 从 reddit 中提取数据,我需要将提取的所有数据推送到字典中,然后将字典数据存储到 PostgreSQL 数据库中,for 循环工作并提取我需要的所有值,但在end 只有最后一个被插入到字典中。我尝试使用列表字典,但相同的值重复了几次。如何将所有数据插入我的字典中?。还测试了我在这里找到的其他解决方案,但出现了错误。 这是我的代码:

class RedditExtract:
    def __init__(self, query, token):
        self.query = query
        self.token = token
        self.consulta = self.query.get("query")

    def searchQuery(self):
        reddit = praw.Reddit(
            client_id=REDDIT_CLIENT_ID,
            client_secret=REDDIT_CLIENT_SECRET,
            user_agent="extracting for reddit",
        )
        subreddit = reddit.subreddit("all").search(self.consulta)
        submission = reddit.submission
        top_subreddit = subreddit
        itemB = {}
        con = Conexion()
        for submission in top_subreddit:
            try:
                user = submission.author
                reditor = reddit.redditor(user)
                itemB["id"] = reditor.id
                print("id: " + itemB["id"])
                itemB["name"] = submission.fullname
                #print("name: " + itemB["name"])
                itemB["username"] = submission.author.name
                #print("username: " + itemB["username"])
                itemB["red"] = 13
                #print("red: " + str(itemB["red"]))
                itemB["type"] = "b"
                #print("type: " + str(itemB["type"]))
                itemB["karma"] = submission.author.total_karma
                #print("karma: " + str(itemB["karma"]))
                itemB["avatar"] = reditor.icon_img
                #print("url icon username: " + itemB["avatar"])
                itemB["extract_date"] = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
                #print("extract date: " + itemB["extract_date"])
                itemB["created_at"] = datetime.fromtimestamp(int(submission.created_utc))
                #print("created at: " + str(itemB["created_at"]))
            except:
                print("No se hallo ID del usuario, se omite el post")

打印出来只是为了评估PRAW提取数据是否正确

PS:我使用 PRAW 7.5.0 和 Pyhton 3.8 PyCharm。

我尝试使用列表来存储每个键的值,然后使用列表来创建字典,但只是重复了几次相同的值。 此外,尝试创建另一个用于存储键和存储值,但缺少许多值。 我想要这样的东西: {'id':'kshdh''jajsjs''kasjs''asmjs'...,'name':'asrat''omes',...} 然后,从该字典中,在 PostgreSQL 数据库中的每一列(键)中插入值(值)。

TABLE: 我实际上得到了这样的命令: {'id': 'ajsgs,jhfhd,ajddg,ahsgys,...','name':'maaa,nnn,...',...} 但最大的问题是所有值都是字符串,我需要 'red' 和 'karma' 是整数,不能在字典中转换一次。 我在 PostgreSQL 中的 table 是这样的:

CREATE TABLE IF NOT EXISTS public.salert_basic
(
    id character varying(255) COLLATE pg_catalog."default" NOT NULL,
    name character varying(255) COLLATE pg_catalog."default",
    username character varying(255) COLLATE pg_catalog."default",
    red integer,
    extract_date timestamp without time zone,
    created_at timestamp without time zone,
    karma integer,
    icon character varying COLLATE pg_catalog."default",
    type character varying COLLATE pg_catalog."default",
    CONSTRAINT salert_basic_pk PRIMARY KEY (id)
)

从 Pyhton 插入数据的代码是这样的:

        Conexion.con.autocommit = True
        curser = Conexion.cursor
        columns = itemB.keys()
        for i in itemB.values():
           sql = '''insert into salert_basic(id,name,username,red,type,karma,icon,extraction_date,created_at) values{};'''.format(i)
        curser.execute(sql)
        Conexion.con.commit()
        Conexion.con.close()

这就是我创建字典的方式:

itemB = defaultdict(list)

然后。我为每个键填充它:

itemB["name"].append(submission.fullname)

最后,为了连接字典中列表的值,我将其用于:

  for key in itemB:
     itemB[key] = ", ".join(itemB[key])

但正如我所说,为了做到这一点,我将整数转换为字符串,这无法放入我的数据库中。 你怎么说? PS: 如何避免重复主键错误?因为有一些重复的 id。

更新:

  1. 我检查了%s的使用,我忘记了。
  2. 嗯...不,我需要“id”键中的所有 id,但每个 id 都与其他 id 分开,不像 ahsgdshjgjsdgs.....,另外,id 是一个 PK,因此不允许重复但我认为在 sql 中使用 IN CONFLICT DO NOTHING 我可以避免它的插入并继续其他的。
  3. 是的,我尝试将每个提交作为一行插入数据库 table,但这让我很头疼。

仍然不完全是您要实现的目标。这是我认为可以满足您要求的尝试:

class RedditExtract:
    def __init__(self, query, token):
        self.query = query
        self.token = token
        self.consulta = self.query.get("query")

    def searchQuery(self):
        reddit = praw.Reddit(
            client_id=REDDIT_CLIENT_ID,
            client_secret=REDDIT_CLIENT_SECRET,
            user_agent="extracting for reddit",
        )
        subreddit = reddit.subreddit("all").search(self.consulta)
        submission = reddit.submission
        top_subreddit = subreddit
        data_list = []
        con = Conexion()
        for submission in top_subreddit:
            item_dict = {}
            try:
                user = submission.author
                reditor = reddit.redditor(user)
                item_dict["id"] = reditor.id
                item_dict["name"] = submission.fullname
                item_dict["username"] = submission.author.name
                item_dict["red"] = 13
                item_dict["type"] = "b"
                item_dict["karma"] = submission.author.total_karma
                item_dict["avatar"] = reditor.icon_img
                item_dict["extract_date"] = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
                item_dict["created_at"] = datetime.fromtimestamp(int(submission.created_utc))
                data_list.append(item_dict)
            except:
                print("No se hallo ID del usuario, se omite el post")

sql = """insert into salert_basic
    (id, name, username, red, type, karma, icon,
    extraction_date, created_at) 
values
    (%(id)s, %(name)s,  %(username)s, %(red)s, %(type)s, %(karma)s, 
    %(icon)s, %(extraction_date)s, %(created_at)s)"""

curser = Conexion.cursor
curser.executemany(sql, data_list)

--If this is a large data set then it will perform better with

from psycopg2.extras import execute_batch

execute_batch(curser, sql, data_list)

以上:

  1. 创建字典列表
  2. 修改 sql 以使用命名占位符,以便可以将字典中的值映射到占位符。
  3. executemany() 或 execute_batch()` 中运行 sql。他们将遍历列表并将每个字典中的值应用到查询字符串中的占位符。