Untitled

mail@pastecode.io avatar
unknown
plain_text
15 days ago
6.1 kB
2
Indexable
Never
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, select, MetaData, Table, Float, DateTime, Boolean, LargeBinary, BigInteger
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 webbrowser
import threading
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

@strawberry.type
class Query:
    @strawberry.field
    def get_product_data(self, user: str, page: int = 1, rows: int = 10) -> List[Record]:
        db = SessionLocal()
        try:
            # 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")
Leave a Comment