Ошибка базы данных: “не все аргументы преобразованы при форматировании строки”, когда я использую pandas.io.sql.to_sql()

#python #mysql #pandas #sqlalchemy #web-crawler

#python #mysql #pandas #sqlalchemy #веб-сканер

Вопрос:

У меня есть таблица:введите описание изображения здесь

И я пытаюсь использовать этот импорт этой таблицы с помощью sqlalchemy, код:

 import sqlalchemy as db
import pandas.io.sql as sql

username = 'root'     
password = 'root'     
host = 'localhost'    
port = '3306'         
database = 'classicmodels'   

engine = db.create_engine(f'mysql pymysql://{username}:{password}@{host}:{port}/{database}')

con = engine.raw_connection() 

#readinto dataframe
df = pd.read_sql(f'SELECT * FROM `{database}`.`offices`;', con)
print(df[:2])
df_append = pd.DataFrame([{'officeCode': 8,'city':'Taipei',
                           'phone':'1234567891','addressLine1':'Taipei DaAn',
                           'addressLine2':'Taipei DaAn2','state':'Taipei',
                           'country':'Taiwan','postalCode':'123','territory':'Asia'}])
df2 = pd.concat([df,df_append],ignore_index=True)
sql.to_sql(frame = df2, name='proj55.address_book5',con=con, if_exists='append',index=False)
  

Но я всегда сталкиваюсь с этими ошибками:

  • Если я передам con = engine.raw_connection() в to_sql() , я получу это:

    • Ошибка базы данных: сбой выполнения в sql ‘ВЫБЕРИТЕ имя ИЗ sqlite_master, ГДЕ type=’table’ И name=?;’: не все аргументы преобразованы при форматировании строки
  • Если я использую con = engine.connect() и передаю в read_sql() , я получу ошибку:

    • Ошибка атрибута: объект ‘Connection’ не имеет атрибута ‘cursor’
  • Если я передам engine в to_sql() и read_sql() , я получу это:

    • Ошибка атрибута: объект ‘Engine’ не имеет атрибута ‘cursor’

Что мне делать?

Комментарии:

1. Попробуйте передать свою engine переменную в read_sql и to_sql вместо передачи con . con это необработанное соединение DBAPI, а не объект SQLAlchemy Connectable .

Ответ №1:

pandas.read_sql использует либо:

  • объект подключения sqlalchemy engine.connect()
  • объект db api только для sqlite

при использовании raw_connection() у вас есть объект подключения db api, поэтому pandas считает, что это соединение с базой данных sqlite (как мы видим в вашей ошибке FROM sqlite_master WHERE )

вам нужно использовать con = engine.connect()

 import sqlalchemy
import pandas
engine = sqlalchemy.create_engine('...')
with engine.connect() as conn:
    print('sqla:', list(conn.execute('select * from users')))
    df = pandas.read_sql('select * from users', conn)
    print('df:', df)
    df.to_sql('users2', conn)
    print('sqla:', list(engine.connect().execute('select * from users2')))
  

выводит:

 sqla: [(1, 'toto'), (2, 'titi'), (3, 'tutu'), (4, 'tata')]
df:    id  name
0   1  toto
1   2  titi
2   3  tutu
3   4  tata
sqla: [(1, 'toto'), (2, 'titi'), (3, 'tutu'), (4, 'tata')]
  

как и ожидалось

Комментарии:

1. Ага. Мы также можем просто передать engine сам.

2. Если я использую engine.connect() , я получу сообщение об ошибке: AttributeError: 'Connection' object has no attribute 'cursor' от pd.read_sql() @Cyril Jouve

Ответ №2:

вы должны поместить list.string.sql, чтобы ему было присвоено значение n-1