22
33from fastapi import Depends
44from loguru import logger
5- from sqlalchemy import inspect , schema , text
65from sqlalchemy .engine import Engine
76from sqlalchemy .pool import StaticPool
8- from sqlmodel import Session , SQLModel , create_engine
7+ from sqlmodel import Session , SQLModel , create_engine , MetaData
8+ from sqlalchemy import text , schema
99
1010from config import Settings , get_settings
1111
1212_engine : Engine | None = None
13+ _metadata : MetaData | None = None
14+
15+
16+ def get_metadata (
17+ settings : Annotated [Settings , Depends (get_settings )],
18+ ) -> MetaData :
19+ """Dependency that provides SQLModel metadata with the correct schema configuration."""
20+ global _metadata
21+
22+ if _metadata is None :
23+ _metadata = MetaData (schema = settings .get_table_schema )
24+
25+ # Optional: Add naming convention for constraints
26+ # _metadata.naming_convention = {
27+ # "ix": "ix_%(column_0_label)s",
28+ # "uq": "uq_%(table_name)s_%(column_0_name)s",
29+ # "ck": "ck_%(table_name)s_%(constraint_name)s",
30+ # "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
31+ # "pk": "pk_%(table_name)s"
32+ # }
33+
34+ return _metadata
35+
36+
37+ MetadataDep = Annotated [MetaData , Depends (get_metadata )]
1338
1439
1540def get_session (
1641 settings : Annotated [Settings , Depends (get_settings )],
1742) -> Generator [Session , Settings , None ]:
1843 with Session (_engine ) as session :
1944 session .connection (
20- execution_options = {"schema_translate_map" : {None : settings .database_schema }}
45+ execution_options = {
46+ "schema_translate_map" : {None : settings .get_table_schema }
47+ }
2148 )
2249 yield session
2350
@@ -35,18 +62,16 @@ def get_engine(_settings: Settings | None = None) -> Engine:
3562 if _settings is None :
3663 _settings = get_settings ()
3764
38- database_url = _settings .database_url
39-
4065 # Configure engine based on database type
4166 engine_args = {"echo" : True }
4267
4368 # Add SQLite-specific settings for in-memory database
44- if database_url == "sqlite://" :
69+ if _settings . database_url . startswith ( "sqlite" ) :
4570 engine_args .update (
4671 {"connect_args" : {"check_same_thread" : False }, "poolclass" : StaticPool }
4772 )
4873
49- _engine = create_engine (database_url , ** engine_args )
74+ _engine = create_engine (_settings . database_url , ** engine_args )
5075
5176 # Enable WAL mode if configured
5277 if _settings .sqlite_wal_mode :
@@ -56,42 +81,29 @@ def get_engine(_settings: Settings | None = None) -> Engine:
5681 # conn.execute(text("PRAGMA synchronous=OFF"))
5782 logger .info ("SQLite WAL mode enabled" )
5883
59- # Initialize database if using SQLModel
60- if (
61- _settings .database_type == "sqlmodel"
62- and _settings .database_schema
63- and not _settings .database_url .startswith ("sqlite" )
64- ):
65- SQLModel .metadata .schema = _settings .database_schema
84+ # Initialize schema if using SQLModel, with a schema if not sqlite
85+ if _settings .database_type == "sqlmodel" :
86+ SQLModel .metadata .schema = _settings .get_table_schema
6687 with _engine .connect () as conn :
6788 conn .execution_options = {
68- "schema_translate_map" : {None : _settings .database_schema }
89+ "schema_translate_map" : {None : _settings .get_table_schema }
6990 }
70- if not conn .dialect .has_schema (conn , _settings .database_schema ):
91+ if not _settings .database_url .startswith (
92+ "sqlite"
93+ ) and not conn .dialect .has_schema (conn , _settings .get_table_schema ):
7194 logger .warning (
72- f"Schema '{ _settings .database_schema } ' not found in database. Creating..."
95+ f"Schema '{ _settings .get_table_schema } ' not found in database. Creating..."
7396 )
74- conn .execute (schema .CreateSchema (_settings .database_schema ))
97+ conn .execute (schema .CreateSchema (_settings .get_table_schema ))
7598 conn .commit ()
7699
77- if _settings .database_type == "sqlmodel" and not _settings .migrate_database :
78- logger .info ("Creating database tables..." )
79-
80- # Check if tables exist before creating them
81- inspector = inspect (_engine )
82- existing_tables = inspector .get_table_names (
83- schema = _settings .database_schema if _settings .database_schema else None
84- )
85- if not existing_tables :
86- # if settings.database_schema:
87- # # Create schema if it doesn't exist
88- # if not inspector.has_schema(settings.database_schema):
89- # logger.info(f"Creating schema '{settings.database_schema}'")
90- # with _engine.begin() as conn:
91- # conn.execute(text(f'CREATE SCHEMA IF NOT EXISTS {settings.database_schema}'))
92- SQLModel .metadata .create_all (_engine )
93- logger .info ("Database tables created successfully" )
94- else :
95- logger .info ("Database tables already exist, skipping creation" )
100+ if not _settings .migrate_database :
101+ SQLModel .metadata .create_all (conn )
102+ conn .commit ()
103+ logger .info ("Database tables created successfully" )
104+ else :
105+ logger .info (
106+ "Database tables already exist or migration is configured, skipping creation"
107+ )
96108
97109 return _engine
0 commit comments