0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(自分用メモ) SQLAlchemy で get, set する列を動的に指定

Last updated at Posted at 2025-03-02

SQLAlchemy で get, set する列を動的に指定する方法。

環境

  • Windows 10

  • Python 3.8

  • SQLAlchemy 1.4.54

    $ pip freeze
    greenlet==3.1.1
    SQLAlchemy==1.4.54
    

結論

  • getattr, setattr を使い、属性名を動的に指定できる
  • 属性名として、Column.key を使用できる

デモ

Chat-GPT 4o の出力を少し改変した。

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base

# SQLite用のエンジン(実際のアプリでは適宜変更)
engine = create_engine("sqlite:///:memory:", echo=True)
SessionLocal = sessionmaker(bind=engine)

# モデル定義
Base = declarative_base()


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), nullable=False)
    email = Column(String(100), nullable=False)

    def __repr__(self):
        return f"<User(id={self.id}, name={self.name}, email={self.email})>"


# テーブル作成
Base.metadata.create_all(engine)

# セッション作成
session = SessionLocal()

users = [User(), User()]
users[0].id = 1
users[0].name = "Alice"
users[0].email = "alice@example.com"
users[1].id = 2
users[1].name = "Bob"
users[1].email = "bob@example.com"
session.add_all(users)
session.commit()

# 例として2つのUserを取得 (仮に存在するとする)
user_a = session.query(User).filter_by(id=1).one()
user_b = session.query(User).filter_by(id=2).one()

# User.email のカラムオブジェクト
col = User.email

# `setattr()` を使用して動的に代入
setattr(user_a, col.key, getattr(user_b, col.key))

# 変更をコミット
session.commit()

# 結果確認
updated_user_a = session.query(User).filter_by(name="Alice").one()
print(updated_user_a)  # email が "bob@example.com" に変更されているはず

デモ出力のプロンプト

sqlalchemy1.4のmodelクラスを1つ例示してください。

session.query() を使用して、User のインスタンスを2つ (user_a, user_b とする) 取得したとします。ここで、user_bのメールアドレスをuser_aにコピーしたければ、通常は user_a.email = user_b.email のように email 属性を使用するとすると思います。ですが col = User.email を使用して user_a[col] = user_b[col] のようにしたいです。できますか。

作ってもらった例をデモとして動かしたいので、テーブルを作成するコードも追加してもらえますか。

※レコードを作成するコードは、最後の質問をする前に自分で作っていたので依頼しなかった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?