【问题标题】:How to integrate python modules with mysql Alchemy using ORM library如何使用 ORM 库将 python 模块与 mysql Alchemy 集成
【发布时间】:2019-06-11 12:14:23
【问题描述】:

我正在尝试更新 mysql 数据库表 所以我从创建 ORM 对象开始,通过使用 UPDATE、WHERE 条件来帮助我减少更新查询的数量

首先,我创建了一个 ORM 变量,因为此 ORM 对象是通过使用另一个 pd.data_frame CSV 中的条件从数据框中过滤的数据 这是我的简单规则,以便轻松创建这样的条件

myOutlook_inBox = pd.read_csv (r'' + mydir + 'test.CSV', usecols= 
['Subject','Body', 'From: (Name)', 'To: (Name)' ], encoding='latin-1')

这是从pd.read_csv中提取的简单ORM数据

replaced_sbj_value = myOutlook_inBox['Subject']
.str.extract(pat='(L(?:DEL|CAI|SIN).\d{5})').dropna()

这个 ORM 正在从 myOutlook_inBox['Subject'] 中提取 csv.column

replaced_sbj_value = myOutlook_inBox['Subject']
.str.extract(pat='(L(?:DEL|CAI|SIN).\d{5})').dropna()

myOutlook_inBox["Subject"] = replaced_sbj_value

这是我用来过滤特定数据的条件

frm_mwfy_to_te = myOutlook_inBox.loc[myOutlook_inBox['From: 
(Name)'].str.contains("mowafy", na=False)
& myOutlook_inBox['To:(Name)'].str.contains("te", 
na=False)].drop_duplicates(keep=False)
frm_mwfy_to_te.Subject

并且这个变量是在mysql数据库中的一个名为Subject的列中过滤的行

filtered_data = all_data
.loc[all_data.site_code.str.contains('|'.join(frm_mwfy_to_te.Subject))]

这是我的 sql 查询,我现在只需要创建一个查询,在名为“site_code”的列中更新名为“pending”过滤器的列,并更新值包含 filtered_data 的行以更新或替换值在pending 列中,值为TE

update_db_query = engine.execute("UPDATE govtracker SET pending = 'TE'  
WHERE site_code = " + filtered_data)

我认为我在错误的情况下解决此问题的任何想法

注意:我不需要在查询中提及旧值我只是想根据过滤后的数据框将同一行中的值更新为我在查询中提到的新值

例如 根据frm_mwfy_to_te.Subject as Subject 是在 csv 文件中调用的列名

假设这个 ORM 的输出frm_mwfy_to_te.Subject

 Subject
 LCAIN20804
 LDELE30434
 LSINI20260

这是我的全部代码

from sqlalchemy import create_engine
import pandas as pd
import os
import csv
import MySQLdb
from sqlalchemy import types, create_engine


# MySQL Connection
MYSQL_USER      = 'root'
MYSQL_PASSWORD  = 'Mharooney'
MYSQL_HOST_IP   = '127.0.0.1'
MYSQL_PORT      = 3306
MYSQL_DATABASE  = 'mydb'

engine = create_engine('mysql+mysqlconnector://'+MYSQL_USER+'
:'+MYSQL_PASSWORD+'@'+MYSQL_HOST_IP+':'+str(MYSQL_PORT)+'/'+MYSQL_DATABASE, 
echo=False)
#engine = create_engine('mysql+mysqldb://root:@localhost:123456/myDB? 
charset=utf8mb4&binary_prefix=true', echo=False)

mydir = (os.getcwd()).replace('\\', '/') + '/'
all_data = pd.read_sql('SELECT * FROM govtracker', engine)
# .drop(['#'], axis=1)
myOutlook_inBox = pd.read_csv(r'' + mydir + 'test.CSV', usecols=['Subject', 
'Body', 'From: (Name)', 'To: (Name)'],
                          encoding='latin-1')
myOutlook_inBox.columns = myOutlook_inBox.columns.str.replace(' ', '')

#this object extract 5 chars and 5 numbers from specific column in csv
replaced_sbj_value = myOutlook_inBox['Subject'].str.extract(pat='(L(?:DEL|CAI|SIN).\d{5})').dropna()

#this columns I want to filter in database
myOutlook_inBox["Subject"] = replaced_sbj_value
# this conditions filters and get and dublicate repeated data from outlook 
exported file
# Condition 1 any mail from mowafy to te
frm_mwfy_to_te = myOutlook_inBox.loc[myOutlook_inBox['From: 
(Name)'].str.contains("mowafy", na=False)
                                 & myOutlook_inBox['To: 
(Name)'].str.contains("te", na=False)].drop_duplicates(
keep=False)
frm_mwfy_to_te.Subject

filtered_data = all_data.loc[all_data.site_code.str.contains
('|'.join(frm_mwfy_to_te.Subject))]

print(myOutlook_inBox)

all_data.replace('\n', '', regex=True)
df = all_data.where((pd.notnull(all_data)), None)
print(df)

print("Success")

print(frm_mwfy_to_te.Subject)
print(filtered_data)
# rows = engine.execute("SELECT * FROM govtracker")#.fetchall()
# print(rows)


update_db_query = engine.execute("UPDATE govtracker SET pending = 'TE'  
WHERE site_code = " + filtered_data)
"""engine = create_engine('postgresql+psycopg2://user:pswd@mydb')
df.to_sql('temp_table', engine, if_exists='replace')"""

# select_db_query = pd.read_sql("SELECT * FROM govtracker", con = engine)

#print(update_db_query)

现在假设这是我的 ORM 的输出,那么我将使用这个 ORM 过滤并从 mysql 数据库中获取这三个值的行,以更新每一行包含这些值,我想更新名为 @987654339 的列@ 和 pending status 在我的 sql 中

这是我的数据库查询

CREATE TABLE `mydb`.`govtracker` (
    `id` INT,
    `site_name` VARCHAR(255),
    `region` VARCHAR(255),
    `site_type` VARCHAR(255),
    `site_code` VARCHAR(255),
    `tac_name` VARCHAR(255),
    `dt_readiness` DATE,
    `rfs` VARCHAR(255),
    `rfs_date` DATE,
    `huawei_1st_submission_date` DATE,
    `te_1st_submission_date` DATE,
    `huawei_2nd_submission_date` DATE,
    `te_2nd_submission_date` DATE,
    `huawei_3rd_submission_date` DATE,
    `te_3rd_submission_date` DATE,
    `acceptance_date_opt` DATE,
    `acceptance_date_plan` DATE,
    `signed_sites` VARCHAR(255),
    `as_built_date` DATE,
    `as_built_status` VARCHAR(255),
    `date_dt` DATE,
    `dt_status` VARCHAR(255),
    `shr_status` VARCHAR(255),
    `dt_planned` INT(255),
    `integeration_status` VARCHAR(255),
    `comments_snags` LONGTEXT,
    `cluster_name` LONGTEXT,
    `type_standalone_colocated` VARCHAR(255),
    `installed_type_standalone_colocated` VARCHAR(255),
    `status` VARCHAR(255),
    `pending` VARCHAR(255),
    `pending_status` LONGTEXT,
    `problematic_details` LONGTEXT,
    `ets_tac` INT(255),
    `region_r` VARCHAR(255),
    `sf6_signed_date` DATE,
    `sf6_signed_comment` LONGTEXT,
    `comment_history` LONGTEXT,
    `on_air_owner` VARCHAR(255),
    `pp_owner` VARCHAR(255),
    `report_comment` LONGTEXT,
    `hu_opt_area_owner` VARCHAR(255),
    `planning_owner` VARCHAR(255),
    `po_number` VARCHAR(255),
    `trigger_date` DATE,
    `as_built_status_tr` VARCHAR(255)
) ENGINE = InnoDB;

另一个重要说明: 在 excel 中,当我在某些列中使用过滤器时,它显示了我选择的列中的所有值让我们说 Pending 是我选择的列,其值 Accepted & PAC in progress Planning TE PP DT FMRolloutIntegrationOpt Team 所以现在所有其余列都有这样的值 所以我应该创建一个类似columns_values 的表并用我拥有的所有这些值填充这个表,因为这些值是静态值 我的案子很容易解决

最后注意:这个数据库是根据现有的 xlsm 文件,但我将数据从 xlsm 推送到 mysql,现在 mysql 是我的主数据库,不是 excel 格式,但我正在通过 csv 文件更新 mysql 数据库,而不是在我的数据库中orm objectfrm_mwfy_to_te.Subject是从csv文件中的数据框中提取的数据

这里有什么想法吗?

我希望一切都足够清楚

这个材料对我有帮助吗?

https://auth0.com/blog/sqlalchemy-orm-tutorial-for-python-developers/#SQLAlchemy-ORM

这叫做 TL;DR

重要说明:过滤数据的值实际上是 pandas 数据框,但仅适用于 CSV 文件中的一列,因为我想像我之前发布的那样使用此数据框列值进行过滤,以更新我刚开始更新的数据库中的某些列一列称为待处理一列,以查看结果,然后我将通过我要创建的脚本的方式更新其他列,以便在我的数据库中使用过滤数据中的这些值进行搜索,例如我有一个名为 LCAIN20804 的值我想取这个值并在数据库表中进行过滤,然后转到名为华为第一次提交日期的列(如果未填写),然后填写当前数据(如果已填写)转到待处理列并用 TE 替换旧值然后转到pending_status 并用等待 TE 接受替换旧值等等这是我要创建的脚本的一小部分 我希望这足够清楚

【问题讨论】:

  • 能否请包含filtered_data 值的sn-p?它看起来像一个 pandas DataFrame,但它有多个列吗?您想更新所有这些列吗?
  • @Ruben Helsloot 感谢您的关注,请在重要说明中查看我的编辑

标签: python mysql pandas


【解决方案1】:

如果你想将pandas DataFrame 转换为SQL 更新语句,最好先将其转换为元组列表,其中元组是新的列值,然后使用engine.executemany (https://stackoverflow.com/a/27743541/5015356 )

values = [tuple(x) for x in filtered_data.values]

query = """
UPDATE govtracker
SET pending = 'TE'  
WHERE site_code = '%s')
"""
connection = engine.connect()
update_db_query = connection.execute(query, values)

对于每个元组(<sitecode>),这将执行更新语句。如果您想更新更多列或扩展 where 子句,只需将其他列添加到 filtered_data,然后在您希望其他值出现的位置添加新的 %s

只要确保列的顺序正确!

【讨论】:

  • 非常感谢您的帮助 tuples 我正在寻找的一个,但是我在运行 proj AttributeError: 'Engine' object has no attribute 'executemany' 后在终端中发现了这个错误我想投票,但我的声誉太低了
  • 抱歉,我更新了答案以便更好地使用 SQLAlchemy
  • 这个我试过了,但我发现另一个不是所有参数都在SQL语句中使用
  • 您确定filtered_data 只有一列吗?执行filtered_data.shape会得到什么?
  • 实际上,filtered_data 显示了数据库中的所有列,但我要过滤的特定列是filtered_data.site_code 对不起,我刚刚醒来
猜你喜欢
  • 2013-05-06
  • 2022-01-18
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多