如何在 SQLAlchemy 中删除 table?
How to delete a table in SQLAlchemy?
我想使用 SQLAlchemy 删除一个 table。
由于我反复测试,所以我想删除table my_users
,这样我每次都可以从头开始。
到目前为止,我正在使用 SQLAlchemy 通过 engine.execute() 方法执行原始 SQL:
sql = text('DROP TABLE IF EXISTS my_users;')
result = engine.execute(sql)
但是,我想知道是否有一些标准的方法可以做到这一点。我能找到的唯一一个是 drop_all()
,但它删除了所有结构,而不仅仅是一个特定的 table:
Base.metadata.drop_all(engine) # all tables are deleted
例如,给出这个非常基本的例子。它由一个 SQLite 基础设施组成,有一个 table my_users
,我在其中添加了一些内容。
from sqlalchemy import create_engine, Column, Integer, String, text
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite://', echo=False)
Base = declarative_base()
class User(Base):
__tablename__ = "my_users"
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
# Create all the tables in the database which are
# defined by Base's subclasses such as User
Base.metadata.create_all(engine)
# Construct a sessionmaker factory object
session = sessionmaker()
# Bind the sessionmaker to engine
session.configure(bind=engine)
# Generate a session to work with
s = session()
# Add some content
s.add(User('myname'))
s.commit()
# Fetch the data
print(s.query(User).filter(User.name == 'myname').one().name)
对于这种特定情况,drop_all()
会起作用,但从我开始拥有多个 table 并且我想保留其他的那一刻起就不方便了。
只需针对 table 对象调用 drop()
。
来自 the docs:
Issue a DROP statement for this Table, using the given Connectable for connectivity.
你的情况应该是:
User.__table__.drop()
如果您遇到如下异常:
sqlalchemy.exc.UnboundExecutionError: Table object 'my_users' is not bound to an Engine or Connection. Execution can not proceed without a database to execute against
您需要通过引擎:
User.__table__.drop(engine)
下面是您可以在 iPython 中执行的示例代码,用于测试在 Postgres
上创建和删除 table
from sqlalchemy import * # imports all needed modules from sqlalchemy
engine = create_engine('postgresql://python:python@127.0.0.1/production') # connection properties stored
metadata = MetaData() # stores the 'production' database's metadata
users = Table('users', metadata,
Column('user_id', Integer),
Column('first_name', String(150)),
Column('last_name', String(150)),
Column('email', String(255)),
schema='python') # defines the 'users' table structure in the 'python' schema of our connection to the 'production' db
users.create(engine) # creates the users table
users.drop(engine) # drops the users table
您还可以使用相同的示例和屏幕截图在 Wordpress 上预览我的文章:oscarvalles.wordpress.com(搜索 SQL Alchemy)。
除了调用 cls.__table__.drop(your_engine)
,您可以试试这个:
Base.metadata.drop_all(bind=your_engine, tables=[User.__table__])
此方法以及 create_all()
方法接受一个可选参数 tables
,它采用 sqlalchemy.sql.schema.Table
个实例的迭代器。
您可以通过这种方式控制要创建或删除哪些表。
对于无法访问 table class 并且只需要通过 table 名称删除 table 然后使用此代码的特殊情况
import logging
from sqlalchemy import MetaData
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
DATABASE = {
'drivername': 'sqlite',
# 'host': 'localhost',
# 'port': '5432',
# 'username': 'YOUR_USERNAME',
# 'password': 'YOUR_PASSWORD',
'database': '/path/to/your_db.sqlite'
}
def drop_table(table_name):
engine = create_engine(URL(**DATABASE))
base = declarative_base()
metadata = MetaData(engine, reflect=True)
table = metadata.tables.get(table_name)
if table is not None:
logging.info(f'Deleting {table_name} table')
base.metadata.drop_all(engine, [table], checkfirst=True)
drop_table('users')
这里更新了@Levon 的回答,因为 MetaData(engine, reflect=True)
现已弃用。如果您无权访问 table class 或想通过其 table 名称删除 table。
from sqlalchemy import MetaData
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
DATABASE = {
'drivername': 'sqlite',
# 'host': 'localhost',
# 'port': '5432',
# 'username': 'YOUR_USERNAME',
# 'password': 'YOUR_PASSWORD',
'database': '/path/to/your_db.sqlite'
}
engine = create_engine(URL(**DATABASE))
def drop_table(table_name, engine=engine):
Base = declarative_base()
metadata = MetaData()
metadata.reflect(bind=engine)
table = metadata.tables[table_name]
if table is not None:
Base.metadata.drop_all(engine, [table], checkfirst=True)
drop_table('users')
否则,您可能更愿意使用 cls.__table__.drop(engine)
和 cls.__table__.create(engine)
,例如
User.__table__.drop(engine)
User.__table__.create(engine)
我想使用 SQLAlchemy 删除一个 table。
由于我反复测试,所以我想删除table my_users
,这样我每次都可以从头开始。
到目前为止,我正在使用 SQLAlchemy 通过 engine.execute() 方法执行原始 SQL:
sql = text('DROP TABLE IF EXISTS my_users;')
result = engine.execute(sql)
但是,我想知道是否有一些标准的方法可以做到这一点。我能找到的唯一一个是 drop_all()
,但它删除了所有结构,而不仅仅是一个特定的 table:
Base.metadata.drop_all(engine) # all tables are deleted
例如,给出这个非常基本的例子。它由一个 SQLite 基础设施组成,有一个 table my_users
,我在其中添加了一些内容。
from sqlalchemy import create_engine, Column, Integer, String, text
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite://', echo=False)
Base = declarative_base()
class User(Base):
__tablename__ = "my_users"
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
# Create all the tables in the database which are
# defined by Base's subclasses such as User
Base.metadata.create_all(engine)
# Construct a sessionmaker factory object
session = sessionmaker()
# Bind the sessionmaker to engine
session.configure(bind=engine)
# Generate a session to work with
s = session()
# Add some content
s.add(User('myname'))
s.commit()
# Fetch the data
print(s.query(User).filter(User.name == 'myname').one().name)
对于这种特定情况,drop_all()
会起作用,但从我开始拥有多个 table 并且我想保留其他的那一刻起就不方便了。
只需针对 table 对象调用 drop()
。
来自 the docs:
Issue a DROP statement for this Table, using the given Connectable for connectivity.
你的情况应该是:
User.__table__.drop()
如果您遇到如下异常:
sqlalchemy.exc.UnboundExecutionError: Table object 'my_users' is not bound to an Engine or Connection. Execution can not proceed without a database to execute against
您需要通过引擎:
User.__table__.drop(engine)
下面是您可以在 iPython 中执行的示例代码,用于测试在 Postgres
上创建和删除 tablefrom sqlalchemy import * # imports all needed modules from sqlalchemy
engine = create_engine('postgresql://python:python@127.0.0.1/production') # connection properties stored
metadata = MetaData() # stores the 'production' database's metadata
users = Table('users', metadata,
Column('user_id', Integer),
Column('first_name', String(150)),
Column('last_name', String(150)),
Column('email', String(255)),
schema='python') # defines the 'users' table structure in the 'python' schema of our connection to the 'production' db
users.create(engine) # creates the users table
users.drop(engine) # drops the users table
您还可以使用相同的示例和屏幕截图在 Wordpress 上预览我的文章:oscarvalles.wordpress.com(搜索 SQL Alchemy)。
除了调用 cls.__table__.drop(your_engine)
,您可以试试这个:
Base.metadata.drop_all(bind=your_engine, tables=[User.__table__])
此方法以及 create_all()
方法接受一个可选参数 tables
,它采用 sqlalchemy.sql.schema.Table
个实例的迭代器。
您可以通过这种方式控制要创建或删除哪些表。
对于无法访问 table class 并且只需要通过 table 名称删除 table 然后使用此代码的特殊情况
import logging
from sqlalchemy import MetaData
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
DATABASE = {
'drivername': 'sqlite',
# 'host': 'localhost',
# 'port': '5432',
# 'username': 'YOUR_USERNAME',
# 'password': 'YOUR_PASSWORD',
'database': '/path/to/your_db.sqlite'
}
def drop_table(table_name):
engine = create_engine(URL(**DATABASE))
base = declarative_base()
metadata = MetaData(engine, reflect=True)
table = metadata.tables.get(table_name)
if table is not None:
logging.info(f'Deleting {table_name} table')
base.metadata.drop_all(engine, [table], checkfirst=True)
drop_table('users')
这里更新了@Levon 的回答,因为 MetaData(engine, reflect=True)
现已弃用。如果您无权访问 table class 或想通过其 table 名称删除 table。
from sqlalchemy import MetaData
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
DATABASE = {
'drivername': 'sqlite',
# 'host': 'localhost',
# 'port': '5432',
# 'username': 'YOUR_USERNAME',
# 'password': 'YOUR_PASSWORD',
'database': '/path/to/your_db.sqlite'
}
engine = create_engine(URL(**DATABASE))
def drop_table(table_name, engine=engine):
Base = declarative_base()
metadata = MetaData()
metadata.reflect(bind=engine)
table = metadata.tables[table_name]
if table is not None:
Base.metadata.drop_all(engine, [table], checkfirst=True)
drop_table('users')
否则,您可能更愿意使用 cls.__table__.drop(engine)
和 cls.__table__.create(engine)
,例如
User.__table__.drop(engine)
User.__table__.create(engine)