How to dynamically choose the database and table based on input with SQLAlchemy?

 Python: How to dynamically choose the database and table based on input with SQLAlchemy?

If you want to dynamically choose the database URL and table based on input, you can use a more flexible approach by creating a factory function to handle this. This will involve dynamically creating the engine and session based on the input, and then dynamically loading the appropriate model.

Here's a step-by-step guide to achieve this:

1. Define a Model Registry

You can maintain a dictionary of model classes for each database. This way, you can dynamically choose the model based on the table name.


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

Base = declarative_base()


# Define models for different tables
class User(Base):
	__tablename__ = 'users'
	id = Column(Integer, primary_key=True)
	name = Column(String(255), default="", nullable=False)


class Product(Base):
	__tablename__ = 'products'
	id = Column(Integer, primary_key=True)
	product_name = Column(String(255), default="", nullable=False)


# Map tables to models
model_registry = {
	'users': User,
	'products': Product
}

# 2. Create a Function to Initialize Session and Model

# This function will create the engine and session based on the input database URL and table name.


 def get_engine_and_session(db_url):
	engine = create_engine(db_url)
	Session = sessionmaker(bind=engine)
	session = Session()
	return engine, session


def get_model_for_table(table_name):
	return model_registry.get(table_name)


def initialize_table(db_url, table_name):
	# Create engine and session
	engine, session = get_engine_and_session(db_url)
	
	# Get the model for the given table name
	model = get_model_for_table(table_name)
	
	if not model:
		raise ValueError(f"No model defined for table '{table_name}'")
	
	# Check if the table exists
	inspector = inspect(engine)
	if not inspector.has_table(model.__tablename__):
		print(f"Creating table '{model.__tablename__}'")
		create_table_for_model(engine, model)
	# Or Create all tables if they don't exist
	# Base.metadata.create_all(engine)
	
	return session, model


def create_table_for_model(engine, model):
	""" Creates only the specific table for the given model."""
	model.metadata.create_all(engine, tables=[model.__table__])

# 3. Here's how you can use the function to dynamically choose the database URL and table:


 if __name__ == "__main__":
	# input_db_url = "mysql+mysqlclient://username:password@localhost/dbname"
	input_db_url = "mysql+pymysql://username:password@localhost/dbname" # if using PyMySQL.
	input_table = "users"  # or "products"
	
	session, model = initialize_table(input_db_url, input_table)
	
	# Example: Add a new record
	if model:
		new_entry = model(name='John Doe') if input_table == 'users' else model(product_name='Gadget')
		session.add(new_entry)
		session.commit()
	
	# Query example
	results = session.query(model).all()
	# Convert to list of dict:
	result_list = [{k: v for k, v in result.__dict__.items() if k != '_sa_instance_state'} for result in results]
	print(result_list)

***Note: You need to install these packages::

  •  pip install sqlalchemy pymysql

  • or:
    pip install sqlalchemy mysqlclient

👉 Download code
: Python SQLAlchemy with dynamically input


Viết nhận xét

Các bạn có thể viết lời nhận xét cho bài viết, nhưng cần tuân thủ một số quy tắc sau:

» Các nhận xét/bình luận phải nghiêm túc, không dung tục, không spam.
» Nội dung phải liên quan tới chủ đề bài viết.
» Viết bằng tiếng việt có dấu hoặc tiếng Anh. Nội dung viết không dấu sẽ bị xóa.
» Hãy để lại tên của bạn khi nhận xét/bình luận, để tôi có thể dễ dàng trả lời bạn khi cần.