如何在 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。
更新:
- 我检查了%s的使用,我忘记了。
- 嗯...不,我需要“id”键中的所有 id,但每个 id 都与其他 id 分开,不像 ahsgdshjgjsdgs.....,另外,id 是一个 PK,因此不允许重复但我认为在 sql 中使用 IN CONFLICT DO NOTHING 我可以避免它的插入并继续其他的。
- 是的,我尝试将每个提交作为一行插入数据库 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)
以上:
- 创建字典列表
- 修改
sql
以使用命名占位符,以便可以将字典中的值映射到占位符。
- 在
executemany()
或 execute_batch()` 中运行 sql
。他们将遍历列表并将每个字典中的值应用到查询字符串中的占位符。
我卡在这部分了。我正在使用 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。
更新:
- 我检查了%s的使用,我忘记了。
- 嗯...不,我需要“id”键中的所有 id,但每个 id 都与其他 id 分开,不像 ahsgdshjgjsdgs.....,另外,id 是一个 PK,因此不允许重复但我认为在 sql 中使用 IN CONFLICT DO NOTHING 我可以避免它的插入并继续其他的。
- 是的,我尝试将每个提交作为一行插入数据库 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)
以上:
- 创建字典列表
- 修改
sql
以使用命名占位符,以便可以将字典中的值映射到占位符。 - 在
executemany()
或 execute_batch()` 中运行sql
。他们将遍历列表并将每个字典中的值应用到查询字符串中的占位符。