我已经重复尝试使用Python中的SQLAlchemy创建一个表
MYTABLENAME
。我通过 SQL 客户端 Dbeaver 删除了所有表,但收到一条错误消息,表明该表存在这样的情况
Traceback (most recent call last):
File "/home/hhh/anaconda3/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context)
File "/home/hhh/anaconda3/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute
cursor.execute(statement, parameters)
psycopg2.ProgrammingError: relation "ix_MYTABLENAME_index" already exists
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "ix_MYTABLENAME_index" already exists
[SQL: 'CREATE INDEX "ix_MYTABLENAME_index" ON "MYTABLENAME" (index)']
我成功创建了表并插入了具有唯一名称的表,但第二次我收到错误,尽管删除了 Dbeaver 中的表。
小例子
from datetime import date
from sqlalchemy import create_engine
import numpy as np
import pandas as pd
def storePandasDF2PSQL(myDF_):
#Store results as Pandas Dataframe to PostgreSQL database.
#
#Example
#df=pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
#dbName= date.today().strftime("%Y%m%d")+"_TABLE"
#engine = create_engine('postgresql://hhh:yourPassword@localhost:1234/hhh')
#df.to_sql(dbName, engine)
df = myDF_
dbName = date.today().strftime("%Y%m%d")+"_TABLE"
engine = create_engine('postgresql://hhh:yourPassword@localhost:1234/hhh')
# ERROR: NameError: name 'table' is not defined
#table.declarative_base.metadata.drop_all(engine) #Drop all tables
#TODO: This step is causing errors because the SQLAlchemy thinks the
#TODO: table still exists even though deleted
df.to_sql(dbName, engine)
清理后端(例如某些挂起的索引)以便使用新数据重新创建表的正确方法是什么?换句话说,如何解决这个错误?
问题可能来自 sqlalchemy 方面,它认为存在索引,因为删除表的消息没有通知 sqlalchemy。有一种删除表的 sqlalchemy 方法
table.declarative_base.metadata.drop_all(engine)
这应该让 Sqlalchemy 获知删除情况。
此答案不涉及重复使用相同的表名,因此不涉及清理 SQLAlchemy 元数据。
不要重复使用表名称,而是将这样的执行时间添加到表名称的末尾
import time
dbName = date.today().strftime("%Y%m%d")+"_TABLE_"+str(time.time())
dbTableName = dbName
因此您的 SQL 开发环境,例如 SQL 客户端锁定连接或特定表,并不重要。在使用 SQLAlchemy 运行 Python 时,关闭 Dbeaver 会有所帮助。
试试这个
import sqlalchemy
from sqlalchemy import inspect
from sqlalchemy import MetaData
# connect to your database
conn_str = '<your connection string>'
engine = sqlalchemy.create_engine(conn_str)
# use the inspector object to see your table names
inspector = inspect(engine)
table_names = inspector.get_table_names()
# get the metadata for your database
metadata = MetaData()
metadata.reflect(bind=engine)
# delete your tables
for table in table_names:
table_obj = metadata.tables[table]
table_obj.metadata.drop_all(engine)
# Verify your tables dropped
table_names = inspector.get_table_names()
# Print the table names
for table in table_names:
print(table)