Skip to content

Commit 02ee414

Browse files
committed
fix: remove redundant Migrate class and add special configure for sqlite
1 parent d0f9f66 commit 02ee414

File tree

2 files changed

+25
-67
lines changed

2 files changed

+25
-67
lines changed

robyn/__init__.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@
2626
from robyn.types import Directory
2727
from robyn.ws import WebSocket
2828

29-
import importlib.util
30-
31-
spec = importlib.util.find_spec("alembic")
32-
if spec is not None and spec.loader is not None:
33-
from robyn.migrate import Migrate
34-
else:
35-
Migrate = None
36-
3729
__version__ = get_version()
3830

3931
config = Config()
@@ -733,5 +725,4 @@ def cors_middleware(request):
733725
"WebSocketConnector",
734726
"WebSocket",
735727
"MCPApp",
736-
"Migrate",
737728
]

robyn/migrate.py

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,12 @@
1414
if spec is None or spec.loader is None:
1515
print("Alembic has not been installed. Please run 'pip install alembic' to install it.")
1616
exit(1)
17-
17+
1818
import alembic
1919
from alembic import command
2020
from alembic.config import Config as AlembicConfig
2121

2222

23-
class _RobynMigrateConfig:
24-
"""Robyn migration configuration."""
25-
26-
def __init__(self, directory: str = 'migrations', **kwargs):
27-
self.directory = directory
28-
self.kwargs = kwargs
29-
30-
3123
class Config(AlembicConfig):
3224
"""Configuration for Robyn migrations."""
3325

@@ -52,54 +44,6 @@ def _get_template_path(self, template=None):
5244
return Path(template)
5345

5446

55-
class Migrate:
56-
"""Robyn extension for database migrations using Alembic."""
57-
58-
def __init__(self, app=None, db=None, directory='migrations', **kwargs):
59-
"""Initialize the extension.
60-
61-
Args:
62-
app: The Robyn application instance
63-
db: The SQLAlchemy database instance
64-
directory: Directory where migration files will be stored
65-
**kwargs: Additional arguments to pass to Alembic
66-
"""
67-
self.app = app
68-
self.db = db
69-
self.directory = directory
70-
self.kwargs = kwargs
71-
72-
if app is not None and db is not None:
73-
self.init_app(app, db, directory, **kwargs)
74-
75-
def init_app(self, app, db=None, directory=None, **kwargs):
76-
"""Initialize the application with this extension.
77-
78-
Args:
79-
app: The Robyn application instance
80-
db: The SQLAlchemy database instance
81-
directory: Directory where migration files will be stored
82-
**kwargs: Additional arguments to pass to Alembic
83-
"""
84-
self.app = app
85-
self.db = db
86-
self.directory = directory or self.directory
87-
self.kwargs = kwargs or self.kwargs
88-
89-
# Register before_request handler to ensure database connection
90-
@app.before_request()
91-
async def ensure_db_connection(request):
92-
# This could be used to ensure database connection is established
93-
# or perform any pre-request database setup
94-
pass
95-
96-
# Register after_request handler to clean up database resources
97-
@app.after_request()
98-
async def cleanup_db_resources(response):
99-
# This could be used to clean up database resources after request
100-
return response
101-
102-
10347
def catch_errors(f):
10448
"""Decorator to catch and handle errors."""
10549

@@ -163,7 +107,7 @@ def _auto_configure_migrations(directory: str, db_url: Optional[str] = None, mod
163107
f.write(content)
164108
print(f"Successfully configured the database URL: {db_url}")
165109

166-
# 配置 env.py
110+
# Configure env.py
167111
if model_path:
168112
env_py_path = os.path.join(directory, 'env.py')
169113
if os.path.exists(env_py_path):
@@ -196,6 +140,28 @@ def _auto_configure_migrations(directory: str, db_url: Optional[str] = None, mod
196140
print(f"Warning: Could not parse the model path {model_path}, please manually configure env.py")
197141

198142

143+
def _special_configure_for_sqlite(directory: str, model_path: Optional[str] = None):
144+
# If the database is SQLite, must add render_as_batch=True in run_migrations_online() to avoid migration errors caused by SQLite's limited support for ALTER TABLE.
145+
if model_path:
146+
env_py_path = os.path.join(directory, 'env.py')
147+
if os.path.exists(env_py_path):
148+
with open(env_py_path, 'r') as f:
149+
content = f.read()
150+
try:
151+
content = content.replace(
152+
" context.configure(\n connection=connection,\n target_metadata=target_metadata,\n process_revision_directives=process_revision_directives,\n )",
153+
" from sqlalchemy.engine import Connection\n def is_sqlite(conn: Connection) -> bool:\n return conn.dialect.name == \"sqlite\"\n context.configure(\n connection=connection,\n target_metadata=target_metadata,\n process_revision_directives=process_revision_directives,\n render_as_batch=is_sqlite(connection),\n )"
154+
)
155+
with open(env_py_path, 'w') as f:
156+
f.write(content)
157+
except ValueError:
158+
print(
159+
"Warning: If your database is SQLite, you need to manually add `render_as_batch=True` in run_migrations_online() to avoid migration errors caused by SQLite's limited support for ALTER TABLE.")
160+
else:
161+
print(
162+
"Warning: If your database is SQLite, you need to manually add `render_as_batch=True` in run_migrations_online() to avoid migration errors caused by SQLite's limited support for ALTER TABLE.")
163+
164+
199165
@catch_errors
200166
def init(directory: str = 'migrations', multidb: bool = False, template: Optional[str] = None, package: bool = False,
201167
db_url: Optional[str] = None, model_path: Optional[str] = None) -> None:
@@ -260,6 +226,7 @@ def init(directory: str = 'migrations', multidb: bool = False, template: Optiona
260226
command.init(config, directory, template=template_path, package=package)
261227

262228
_auto_configure_migrations(directory, db_url, model_path)
229+
_special_configure_for_sqlite(directory, model_path)
263230

264231

265232
@catch_errors

0 commit comments

Comments
 (0)