Untitled
unknown
plain_text
6 months ago
6.2 kB
2
Indexable
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, select, MetaData, Table, Float, DateTime, Boolean, LargeBinary, BigInteger, text from sqlalchemy.orm import relationship, sessionmaker, declarative_base from fastapi import FastAPI, Depends, HTTPException import strawberry from strawberry.fastapi import GraphQLRouter from typing import Optional, List from datetime import datetime import uvicorn from strawberry.schema.config import StrawberryConfig import dataclasses # Database setup DATABASE_URL = "mysql+pymysql://jsa_dev_admin:RM#AXR02NhAp@itx-acm-jsa-mdm-dev.czijpxum5el7.us-east-1.rds.amazonaws.com/jsamdm_dev" engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() metadata = MetaData() # Step 1: Define your static models first (User, UserCountry, UserTherapeutic) class User(Base): __tablename__ = 'mdm_users' MDM_USER_ID = Column(Integer, primary_key=True) MDM_LOGIN = Column(String, unique=True) countries = relationship('UserCountry', back_populates='user') therapeutics = relationship('UserTherapeutic', back_populates='user') class UserCountry(Base): __tablename__ = 'mdm_users_countries' USER_CNTRY_ID = Column(Integer, primary_key=True) USER_ID = Column(Integer, ForeignKey('mdm_users.MDM_USER_ID')) COUNTRY_ID = Column(Integer) user = relationship('User', back_populates='countries') class UserTherapeutic(Base): __tablename__ = 'mdm_users_therapeutics' USER_TA_ID = Column(Integer, primary_key=True) USER_ID = Column(Integer, ForeignKey('mdm_users.MDM_USER_ID')) TA_ID = Column(Integer) user = relationship('User', back_populates='therapeutics') # Step 2: Dynamically reflect the mdm_product_view table table_name = 'mdm_product_view' table = Table(table_name, metadata, autoload_with=engine) # Reflect column names and primary keys column_names = table.columns.keys() primary_keys = [key.name for key in table.primary_key.columns] if not primary_keys: primary_keys = ['RECORD_ID'] # Use default primary key if none is found # Dynamically create the ORM model attributes = {'__tablename__': table_name} for column in table.columns: column_type = column.type if column.name in primary_keys: attributes[column.name] = Column(column_type, primary_key=True) # Treat as primary key else: attributes[column.name] = Column(column_type) # Non-primary columns DynamicModel = type('DynamicModel', (Base,), attributes) # Step 3: Define GraphQL schema and types dynamically based on reflected columns # Function to map SQLAlchemy types to GraphQL types def get_graphql_type(sqlalchemy_type): if isinstance(sqlalchemy_type, String): return Optional[str] elif isinstance(sqlalchemy_type, Integer): return Optional[int] elif isinstance(sqlalchemy_type, BigInteger): return Optional[int] elif isinstance(sqlalchemy_type, Float): return Optional[float] elif isinstance(sqlalchemy_type, DateTime): return Optional[str] # Use String for datetime elif isinstance(sqlalchemy_type, Boolean): return Optional[bool] elif isinstance(sqlalchemy_type, LargeBinary): return Optional[str] # Use String for binary data else: return Optional[str] # Default to String if type is not explicitly handled # Create Strawberry type dynamically based on table columns @strawberry.type class Record: pass fields = [] for column in table.columns: graphql_type = get_graphql_type(column.type) fields.append((column.name, graphql_type)) Record = strawberry.type(dataclasses.make_dataclass('Record', fields)) # Step 4: Define GraphQL resolver for fetching product data and executing the stored procedure @strawberry.type class Query: @strawberry.field def get_product_data(self, user: str, page: int = 1, rows: int = 10) -> List[Record]: db = SessionLocal() try: # Call the stored procedure to dynamically update the views db.execute(text("CALL jsamdm_qa.productViewSP()")) db.commit() # Fetch user details and associated countries and therapeutic areas user_query = db.execute(select(User).filter_by(MDM_LOGIN=user)) user_obj = user_query.scalar_one_or_none() if user_obj is None: raise HTTPException(status_code=404, detail="User not found") # Get country and TA IDs associated with the user country_ids = [uc.COUNTRY_ID for uc in user_obj.countries] ta_ids = [ut.TA_ID for ut in user_obj.therapeutics] # Build dynamic SQL query query = db.query(DynamicModel).filter(DynamicModel.CURRENT_RECORD == 1) if country_ids: query = query.filter(DynamicModel.COUNTRY_ID.in_(country_ids)) if ta_ids: query = query.filter(DynamicModel.TH_AREA.in_(ta_ids)) # Apply pagination query = query.offset((page - 1) * rows).limit(rows) results = query.all() # Convert results into Record type data_list = [] for result in results: data = {} for column in column_names: value = getattr(result, column) if isinstance(value, datetime): value = value.isoformat() data[column] = value data_list.append(Record(**data)) return data_list finally: db.close() # Step 5: Set up the FastAPI and GraphQL routes # Create the Strawberry schema schema = strawberry.Schema(query=Query, config=StrawberryConfig(auto_camel_case=False)) # Set up FastAPI and GraphQL app = FastAPI() @app.get("/") def read_root(): return {"message": "Welcome to the FastAPI application. Go to /graphql to access the GraphQL interface."} graphql_app = GraphQLRouter(schema) app.include_router(graphql_app, prefix="/graphql") # Step 6: Run the FastAPI application if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)
Editor is loading...
Leave a Comment