我正在尝试创建一个存储推文的SQLite数据库。每天我都会调用API并获得100k左右的推文以进行查询。
鉴于Twitter API可以追溯到7天,某些推文的某些值必然会发生变化(转推,收藏等数量),我需要一种方法来更新已经存在于数据库中的每条推文
这就是我将新推文添加到db中的方式(其中'parsed'是一个dicts列表):
# query to add each tweet to the database
for tweet in parsed:
c.execute("INSERT OR IGNORE INTO tweets VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
[tweet['id'],
tweet['url'],
tweet['created_at'],
tweet['hashtags'],
tweet['favorite_count'],
tweet['user_mentions'],
tweet['text'],
tweet['user_verified'],
tweet['user_following_count'],
tweet['retweet_count'],
tweet['user_name'],
tweet['user_id'],
tweet['user_screen_name'],
tweet['geo'],
tweet['lang'],
tweet['user_followers_count']]
)
这是我到目前为止更新推文的查询:
update_tweet_query = '''UPDATE tweets
SET url = ? ,
created_at = ? ,
hashtags = ? ,
favorite_count = ? ,
user_mentions = ? ,
text = ? ,
user_verified = ? ,
user_following_count = ? ,
retweet_count = ? ,
user_name = ? ,
user_id = ? ,
user_screen_name = ? ,
geo = ? ,
lang = ? ,
user_followers_count = ?
WHERE id = ?'''
但我不确定如何离开这里......我是否走在正确的轨道上?有更好的方法吗?
提前致谢!
答案 0 :(得分:0)
回答了我自己的问题...由于只有两个值会发生变化(最喜欢的计数和转发计数),因此更新每个值都没有用。因此,在解析数据时,我创建了另一个具有流体/动态值的dict,并使用以下内容更新了数据库:
@Transactional
@RequestMapping(value = "/{match:[0-9]+}/results", method = RequestMethod.POST)
public ResultResource createResult(@PathVariable Match match,
@Validated(Result.Creating.class)
@RequestBody Result result) {
if (match == null) throw new ResourceNotFoundException();
result.setScorecard(scorecardRepository
.findById(result.getScorecard().getId()));
if (result.getScorecard() == null) {
throw new ScorecardDoesNotExistException();
}
result.setMatch(match);
//remove null scores
result.getScores().removeIf(
fieldResult -> fieldResult.getScore() == null
);
//replace transient robot with entity from database
Robot existingRobot = robotRepository
.findByNumberAndGame(result.getRobot().getNumber(),result.getRobot().getGame());
if (existingRobot == null) { //create new robot
//find team for this robot
Team existingTeam = teamRepository
.findByNumberAndGameType(
result.getRobot().getNumber(),
result.getScorecard().getGame().getType());
if (existingTeam == null) {
Team team = new Team();
team.setNumber(result.getRobot().getNumber());
team.setGameType(result.getMatch().getEvent().getGame().getType());
team.setDistrict(result.getMatch().getEvent().getDistrict());
teamRepository.save(team);
result.getRobot().setTeam(team);
}
else result.getRobot().setTeam(existingTeam);
result.getRobot().setGame(result.getMatch().getEvent().getGame());
robotRepository.save(result.getRobot());
entityManager.refresh(result.getRobot());
} else result.setRobot(existingRobot);
List<Robot> all = robotRepository.findAll();
//replace transient FieldSections with entities from database
//todo: reduce database hits
//noinspection ResultOfMethodCallIgnored
result.getScores().stream()
.peek(fieldResult -> fieldResult.setField(
fieldSectionRepository.findByIdAndScorecard(
fieldResult.getField().getId(),
result.getScorecard())))
.peek(fieldResult -> {
if (fieldResult.getField() == null)
throw new ScoresDoNotExistException();
})
.forEach(fieldResult->fieldResult.setResult(result));
if (!result.scoresMatchScorecardSections()) {
throw new ScoresDoNotMatchScorecardException();
}
if (!result.allMissingScoresAreOptional()) {
throw new RequiredScoresAbsentException();
}
if (!result.gameMatchesScorecard()) {
throw new GameDoesNotMatchScorecardException();
}
resultRepository.save(result);
match.getRobots().add(result.getRobot());
result.getRobot().getMatches().add(match);
robotRepository.save(result.getRobot());
matchRepository.save(match);
entityManager.refresh(result);
entityManager.refresh(result.getRobot());
entityManager.refresh(match);
return new ResultResourceAssembler().toResource(result);
}