使用 python 脚本比较 MongoDB 和 MySQL 之间的数据

Compare data between MongoDB and MySQL using python script

我正在开发一个 Django 应用程序,该应用程序同时使用 MySQL 和 MongoDB 来存储其数据。我需要做的是比较存储在 MongoDB 的集合中和存储在 MySQL 的 table.

中的数据

例如,我的 MySQL 数据库包含 table“关系”,它是使用以下方法创建的:

CREATE TABLE relations (service_id int, beneficiary_id int, PRIMARY KEY (service_id, beneficiary_id));

我的 MongoDB 包含一个名为“relation”的集合,它应该存储与 MySQL 中的关系 table 相同的数据。以下是“关系”合集的一份文件:

{'_id': 0, 'service_id': 1, 'beneficiary_id': 32}

我试图创建一个 python 脚本来比较 MySQL 中的关系 table 和 Mongo 中的关系集合之间的数据。该脚本的工作原理如下:

mysql_relations = Relations.objects.values('beneficiary_id', 'service_id')
mongo_relations_not_in_mysql = relations_mongodb.find({'$nor':list(mysql_relations)})

mongo_relations = relations_mongodb.find({}, {'_id': 0, 'beneficiary_id':1, 'service_id': 1})
filter_list = Q()
for mongo_relation in mongo_relations:
    filter_list &= Q(mongo_relation)
mysql_relations_not_in_mongo = Relations.objects.exclude(filter_list)

但是,此代码需要很长时间。 我认为主要问题是因为主键由 2 列组成,需要使用 Q() 和 '$nor'。

你有什么建议?

以防万一有人感兴趣,我使用了以下解决方案来优化数据比较。

(想法是创建一个临时的 MySQL Table 来存储 mongo 的数据,然后在 MySQL table)。代码如下:

  1. 从 MongoDB

    获取关系
    mongo_relations = relations_mongodb.find({}, {'_id': 0, 'service_id': 1, 'beneficiary_id': 1})
    
  2. 创建临时 MySQL table 来存储 MongoDB 的关系

    cursor = connection.cursor()
    cursor.execute(
        "CREATE TEMPORARY TABLE temp_relations (service_id int, beneficiary_id int, INDEX `id_related` (`service_id`, `beneficiary_id`) );"
    )
    
  3. 插入 MongoDB 的关系而不是刚刚创建的临时 table

    cursor.executemany(
        'INSERT INTO temp_relations (service_id, beneficiary_id) values (%(service_id)s, %(beneficiary_id)s) ',
            list(mongo_relations)
    )
    
  4. 获取 MongoDB 中不存在的关系 MySQL

    cursor.execute(
        "SELECT service_id, beneficiary_id FROM temp_relations WHERE (service_id, beneficiary_id) NOT IN ("
            "SELECT service_id, beneficiary_id FROM relations);"
    )
    mongo_relations_not_in_mysql = cursor.fetchall()
    
  5. 获取 MySQL MongoDB

    中不存在的关系
    cursor.execute(
        "SELECT id, service_id, beneficiary_id, date FROM relations WHERE (service_id, beneficiary_id) not IN ("
            "SELECT service_id, beneficiary_id FROM temp_relations);"
    )
    mysql_relations_not_in_mongo = cursor.fetchall()
    cursor.close()   # Close the connection to MySQL