Skip to content

Commit 94dff5b

Browse files
vishalshenoycodegen-bot
andauthored
SQLAlchemy 1.6 to 2.0 run.py (#35)
* . * . * select --------- Co-authored-by: codegen-bot <team+codegenbot@codegen.sh>
1 parent e16750d commit 94dff5b

File tree

5 files changed

+105
-175
lines changed

5 files changed

+105
-175
lines changed

examples/sqlalchemy_1.6_to_2.0/output_repo/database.py

Lines changed: 0 additions & 10 deletions
This file was deleted.

examples/sqlalchemy_1.6_to_2.0/output_repo/main.py

Lines changed: 0 additions & 102 deletions
This file was deleted.

examples/sqlalchemy_1.6_to_2.0/output_repo/models.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

examples/sqlalchemy_1.6_to_2.0/output_repo/schemas.py

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import codegen
2+
from codegen import Codebase
3+
from codegen.sdk.core.detached_symbols.function_call import FunctionCall
4+
from codegen.sdk.core.expressions.chained_attribute import ChainedAttribute
5+
6+
7+
@codegen.function("sqlalchemy-1.6-to-2.0")
8+
def run(codebase: Codebase):
9+
"""
10+
Convert SQLAlchemy 1.6 codebases to 2.0.
11+
"""
12+
files_modified = 0
13+
functions_modified = 0
14+
15+
print("\nStarting SQLAlchemy 1.6 to 2.0 migration...")
16+
17+
for file in codebase.files:
18+
file_modified = False
19+
print(f"\nProcessing file: {file.path}")
20+
21+
# Step 1: Convert Query to Select
22+
for call in file.function_calls:
23+
if call.name == "query":
24+
chain = call
25+
while chain.parent and isinstance(chain.parent, ChainedAttribute):
26+
chain = chain.parent
27+
28+
original_code = chain.source
29+
new_query = chain.source.replace("query(", "select(")
30+
if "filter(" in new_query:
31+
new_query = new_query.replace(".filter(", ".where(")
32+
if "filter_by(" in new_query:
33+
model = call.args[0].value
34+
conditions = chain.source.split("filter_by(")[1].split(")")[0]
35+
new_conditions = [f"{model}.{cond.strip().replace('=', ' == ')}" for cond in conditions.split(",")]
36+
new_query = f".where({' & '.join(new_conditions)})"
37+
if "execute" not in chain.parent.source:
38+
new_query = f"execute({new_query}).scalars()"
39+
40+
print(f"\nConverting query in {file.path}:\n")
41+
print("Original code:")
42+
print(original_code)
43+
print("\nNew code:")
44+
print(new_query)
45+
print("-" * 50)
46+
47+
chain.edit(new_query)
48+
file_modified = True
49+
functions_modified += 1
50+
51+
# Step 2: Modernize ORM Relationships
52+
for cls in file.classes:
53+
for attr in cls.attributes:
54+
if isinstance(attr.value, FunctionCall) and attr.value.name == "relationship":
55+
if "lazy=" not in attr.value.source:
56+
original_rel = attr.value.source
57+
new_rel = original_rel + ', lazy="select"'
58+
if "backref" in new_rel:
59+
new_rel = new_rel.replace("backref", "back_populates")
60+
61+
print(f"\nUpdating relationship in class {cls.name}:\n")
62+
print("Original code:")
63+
print(original_rel)
64+
print("\nNew code:")
65+
print(new_rel)
66+
print("-" * 50)
67+
68+
attr.value.edit(new_rel)
69+
file_modified = True
70+
functions_modified += 1
71+
72+
# Step 3: Convert Column Definitions to Type Annotations
73+
for cls in file.classes:
74+
for attr in cls.attributes:
75+
if "Column(" in attr.source:
76+
original_attr = attr.source
77+
new_attr = original_attr.replace("Column", "mapped_column")
78+
type_hint = "Mapped" + original_attr.split("= Column")[1]
79+
new_attr = f"{attr.name}: {type_hint}"
80+
81+
print(f"\nUpdating column definition in class {cls.name}:\n")
82+
print("Original code:")
83+
print(original_attr)
84+
print("\nNew code:")
85+
print(new_attr)
86+
print("-" * 50)
87+
88+
attr.edit(new_attr)
89+
file_modified = True
90+
functions_modified += 1
91+
92+
if file_modified:
93+
files_modified += 1
94+
95+
print("\nMigration complete:")
96+
print(f"Files modified: {files_modified}")
97+
print(f"Functions modified: {functions_modified}")
98+
99+
100+
if __name__ == "__main__":
101+
repo_path = "./input_repo"
102+
print("Initializing codebase...")
103+
codebase = Codebase(repo_path)
104+
print("Running SQLAlchemy 1.6 to 2.0 codemod...")
105+
run(codebase)

0 commit comments

Comments
 (0)