web-dev-qa-db-ja.com

SQLAlchemyでテーブルを削除する方法は?

SQLAlchemyを使用してテーブルを削除したい。

私は何度も何度もテストしているので、毎回ゼロから始められるように、テーブル_my_users_を削除したいと思います。

これまでのところ、SQLAlchemyを使用して engine.execute() メソッドで生のSQLを実行しています。

_sql = text('DROP TABLE IF EXISTS my_users;')
result = engine.execute(sql)
_

しかし、そうするための標準的な方法があるのだろうか。私が見つけることができた唯一のものは drop_all() ですが、1つの特定のテーブルだけでなく、すべての構造を削除します。

_Base.metadata.drop_all(engine)   # all tables are deleted
_

たとえば、この非常に基本的な例を考えます。これは、コンテンツを追加する単一のテーブル_my_users_を持つSQLiteインフラストラクチャで構成されています。

_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()は機能しますが、複数のテーブルを作成し始め、他のテーブルを保持したい瞬間からは便利ではありません。

33
fedorqui

テーブルオブジェクトに対してdrop()を呼び出すだけです。 ドキュメント から:

接続に指定されたConnectableを使用して、このテーブルのDROPステートメントを発行します。

あなたの場合、次のようになります。

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)
43
daveoncode

cls.__table__.drop(your_engine)を呼び出す代わりに、これを試すことができます:

_Base.metadata.drop_all(bind=your_engine, tables=[User.__table__])
_

このメソッドとcreate_all()メソッドは、_sqlalchemy.sql.schema.Table_インスタンスの反復子を取るオプションの引数tablesを受け入れます。

この方法で、どのテーブルを作成または削除するかを制御できます。

12
WeiHao

以下は、Postgresでテーブルの作成と削除をテストするためにiPythonで実行できるサンプルコードです。

from sqlalchemy import * # imports all needed modules from sqlalchemy

engine = create_engine('postgresql://python:[email protected]/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を検索)で記事をプレビューすることもできます。

4
oscarvalles

テーブルクラスへのアクセス権がなく、テーブル名でテーブルを削除するだけの特別な場合には、このコードを使用できます

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')
1
Levon