Flask එක්ක Database වැඩ - SQLAlchemy Sinhala Guide | Python Web Dev

Mastering Flask Databases with SQLAlchemy: A Practical Sinhala Guide
Mastering Flask Databases with SQLAlchemy: A Practical Sinhala Guide
ආයුබෝවන් යාළුවනේ! අද අපි කතා කරන්න යන්නේ වෙබ් ඇප්ලිකේෂන් එකක් හදනකොට අත්යවශ්යම දෙයක් ගැන – ඒ තමයි දත්ත ගබඩා (Databases). අපි හදන ඕනෑම ඇප් එකකට තොරතුරු ගබඩා කරගන්න, ආපහු ගන්න, වෙනස් කරන්න සහ අවශ්ය නැති දේවල් අයින් කරන්න දත්ත ගබඩාවක් නැතුව බැහැ නේද? විශේෂයෙන්ම Python සහ Flask Framework එක පාවිච්චි කරන ඔයාට මේ දත්ත ගබඩා එක්ක වැඩ කරන එක පහසු කරගන්න පුළුවන් බලගතු මෙවලමක් තමයි SQLAlchemy කියන්නේ.
මේ ලිපියෙන් අපි බලමු:
- ORM (Object-Relational Mapper) කියන්නේ මොකක්ද කියලා.
- SQLAlchemy කියන්නේ මොකක්ද? ඒක Flask එක්ක සම්බන්ධ කරගන්නේ කොහොමද?
- දත්ත ගබඩාවක (අපි මේකට SQLite පාවිච්චි කරමු) මේස හෙවත් Models හදාගන්නේ කොහොමද?
- අපේ දත්ත එකතු කරන (Create), කියවන (Read), වෙනස් කරන (Update) සහ අයින් කරන (Delete) විදිහ (මේවට අපි CRUD Operations කියනවා).
- ඔයාට එන්න පුළුවන් පොදු ගැටළු සහ ඒවට විසඳුම්, ඒ වගේම හොඳම ක්රම (Best Practices).
ඉතින්, ඔයා Flask එක්ක දත්ත ගබඩා ගැන තියෙන බය නැති කරගෙන, professional developer කෙනෙක් විදිහට මේ දේවල් කරන හැටි ඉගෙන ගන්න ලෑස්තිද? එහෙනම් අපි පටන් ගමු!
ORM (Object-Relational Mapper) කියන්නේ මොකක්ද?
හිතන්න, ඔයා Python වලින් කෝඩ් ලියනවා. ඒත් දත්ත ගබඩාවක් තියෙන්නේ SQL වලින්. මේ දෙක අතර පොඩි පරතරයක් තියෙනවා නේද? ORM (Object-Relational Mapper) එකක් කියන්නේ මේ පරතරය පුරවන, අපේ Python කෝඩ් එකයි, දත්ත ගබඩාවයි අතර තියෙන බ්රිජ් එකක් වගේ දෙයක්.
සරලව කිව්වොත්, ORM එකක් මගින් අපිට පුළුවන් දත්ත ගබඩාවේ තියෙන මේස (tables) අපේ Python වල තියෙන objects විදිහට පාවිච්චි කරන්න. ඒ කියන්නේ අපිට දත්ත ගබඩාවට යමක් එකතු කරන්න, වෙනස් කරන්න, හොයන්න SQL Queries ලියන්න ඕනේ නැහැ. ඒ වෙනුවට අපිට පුළුවන් Python කෝඩ් විතරක් පාවිච්චි කරන්න. ORM එක අපිට ඕන කරන SQL කෝඩ් එක ස්වයංක්රීයව හදලා දත්ත ගබඩාවත් එක්ක වැඩ කරනවා.
ORM එකක් පාවිච්චි කිරීමේ වාසි:
- පහසුව (Ease of Use): SQL ලියන්න ඕනේ නැති නිසා කෝඩ් ලියන එක ගොඩක් පහසු වෙනවා.
- කියවීමේ පහසුව (Readability): අපේ Python objects පාවිච්චි කරන නිසා කෝඩ් එක කියවන්න සහ තේරුම් ගන්න පහසුයි.
- දත්ත ගබඩා ස්වාධීනත්වය (Database Independence): ඔයාගේ ORM එක විවිධ වර්ගයේ දත්ත ගබඩා (PostgreSQL, MySQL, SQLite) එක්ක වැඩ කරන්න පුළුවන්. ඒ නිසා අවශ්ය වුණොත් දත්ත ගබඩාව වෙනස් කරන එක ලේසියි.
- ආරක්ෂාව (Security): SQL Injection වැනි ප්රහාර වලින් යම් ආරක්ෂාවක් ලැබෙනවා, මොකද ORM එක SQL queries නිවැරදිව sanitize කරන නිසා.
SQLAlchemy - Python වලට දත්ත ගබඩා සම්බන්ධ කරන පාලම
Python වලට තියෙන පවර්ෆුල්ම සහ ජනප්රියම ORM එකක් තමයි SQLAlchemy කියන්නේ. මේක හුදෙක් ORM එකක් විතරක් නෙවෙයි, දත්ත ගබඩා එක්ක වැඩ කරන්න අවශ්ය හැම දෙයක්ම වගේ මේකේ අඩංගුයි. Flask Framework එක එක්ක SQLAlchemy පාවිච්චි කරන්න නම්, අපි Flask-SQLAlchemy කියන extension එක පාවිච්චි කරනවා. මේක SQLAlchemy එක Flask එක්ක seamless විදිහට integrate කරනවා.
Flask-SQLAlchemy ස්ථාපනය කරගමු:
මුලින්ම ඔයාගේ project එකේ virtual environment එක activate කරලා පහත command එක ටයිප් කරන්න:
pip install Flask Flask-SQLAlchemy
මේකෙන් Flask සහ Flask-SQLAlchemy දෙකම install වෙනවා.
Flask එක්ක SQLAlchemy සම්බන්ධ කරගමු - SQLite උදාහරණයක්
අපි මේකට SQLite දත්ත ගබඩාවක් පාවිච්චි කරමු. SQLite කියන්නේ server එකක් අවශ්ය නැති, file එකක් විදිහට තියෙන පොඩි දත්ත ගබඩාවක්. Development වලට සහ පොඩි applications වලට මේක ගොඩක් හොඳයි. අපි පල්ලෙහා තියෙන විදිහට Flask application එක setup කරගමු.
පළමු පියවර: Flask App එක නිර්මාණය කිරීම
app.py
කියලා file එකක් හදාගෙන පහත කෝඩ් එක ලියන්න:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# Database Configuration
# SQLite database file eka 'site.db' kiyala hadanawa
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Me optional eka False karanna one
db = SQLAlchemy(app)
# Define a simple route to check if the app is running
@app.route('/')
def home():
return "Hello, Flask with SQLAlchemy!"
if __name__ == '__main__':
# Database tables create karanna application context ekak athule
with app.app_context():
db.create_all()
app.run(debug=True)
මේ කෝඩ් එකෙන් මොකක්ද වෙන්නේ කියලා බලමු:
from flask import Flask
: Flask import කරගන්නවා.from flask_sqlalchemy import SQLAlchemy
: Flask-SQLAlchemy extension එක import කරගන්නවා.app = Flask(__name__)
: අපේ Flask application එක initialize කරනවා.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
: මේකෙන් කියන්නේ අපේ database එක මොකක්ද, කොහෙද තියෙන්නේ කියලා.sqlite:///site.db
කියන්නේsite.db
කියන file එකේ අපේ SQLite database එක තියෙනවා කියන එක. මේ file එක ඔයාගේ project root එකේ හැදෙනවා.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
: මේක True කරලා තිබ්බොත්, database එකේ වෙනස්කම් track කරනවා. ඒක memory එකට බලපාන නිසා, බොහොමයක් වෙලාවට අපි මේකFalse
කරනවා.db = SQLAlchemy(app)
: SQLAlchemy instance එක අපේ Flask app එකට සම්බන්ධ කරනවා.with app.app_context(): db.create_all()
: මේක ගොඩක් වැදගත්. Flask context එකක් නැතුව database operations කරන්න බැහැ.db.create_all()
කියන එකෙන් අපි පස්සේ හදන database models වලට අදාළ tables database එකේ හදනවා. මේක මුලින්ම app එක run වෙනකොට විතරක් කරන්න ඕනේ. Tables හැදුවට පස්සේ නැවත නැවත කරන්න අවශ්ය නැහැ.
දත්ත ආකෘති (Models) නිර්මාණය කරමු
දැන් අපි බලමු දත්ත ගබඩාවේ tables විදිහට පාවිච්චි කරන models කොහොමද හදාගන්නේ කියලා. මේවා Python classes විදිහට තමයි define කරන්නේ. මේ class එකේ attributes තමයි database table එකේ columns වෙන්නේ.
අපි සරල User
model එකක් හදමු. මේකේ id
, username
, email
, සහ active
කියන columns තියෙනවා.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# User Model eka mehema hadanawa
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
active = db.Column(db.Boolean, default=True)
def __repr__(self):
return f"<User {self.username}>"
@app.route('/')
def home():
return "Hello, Flask with SQLAlchemy!"
if __name__ == '__main__':
with app.app_context():
db.create_all() # Meeta passe User table eka hadanawa
app.run(debug=True)
මෙහිදී,
class User(db.Model):
: අපිUser
කියන class එකdb.Model
එකෙන් inherit කරනවා. මේකෙන් තමයි SQLAlchemy ට මේක database model එකක් කියලා තේරෙන්නේ.id = db.Column(db.Integer, primary_key=True)
:id
කියන්නේ integer type එකක්.primary_key=True
කියන්නේ මේක unique වෙනවා වගේම table එකට අඳුනගන්න පුළුවන් ප්රධානම Column එක කියන එක. මේවා ස්වයංක්රීයව incremental (එකෙන් එකට වැඩි වෙනවා) වෙනවා.username = db.Column(db.String(80), unique=True, nullable=False)
:username
කියන්නේ string type එකක් (VARCHAR
වගේ).80
කියන්නේ උපරිම character ගාන.unique=True
කියන්නේ මේ Column එකේ values එකිනෙකට වෙනස් විය යුතුයි කියන එක (එකම username එක දෙන්නෙකුට බැහැ).nullable=False
කියන්නේ මේ Column එක හිස් වෙන්න බැහැ (අනිවාර්යයෙන්ම value එකක් තියෙන්න ඕනේ).email = db.Column(db.String(120), unique=True, nullable=False)
:email
එකත්username
වගේමයි.active = db.Column(db.Boolean, default=True)
:active
කියන්නේ True/False value එකක් ගන්න පුළුවන් Boolean type එකක්.default=True
කියන්නේ value එකක් නොදුන්නොත් පෙරනිමියෙන් True වෙනවා කියන එක.def __repr__(self):
: මේ method එකෙන් අපිට පුළුවන්User
object එකක් print කරනකොට ඒකේ නියෝජනය විදිහට මොකක්ද පෙන්වන්න ඕනේ කියලා කියන්න. මේක debugging වලට ගොඩක් ප්රයෝජනවත්.
දැන් ඔයා මේ කෝඩ් එක save කරලා run කලාම, site.db
කියන file එක ඔයාගේ project folder එකේ හැදිලා, ඒක ඇතුලේ User
කියන table එකත් හැදෙනවා.
CRUD මෙහෙයුම් (Create, Read, Update, Delete)
දැන් අපි බලමු අපේ User
model එක පාවිච්චි කරලා දත්ත ගබඩාවට තොරතුරු එකතු කරන්නේ, හොයන්නේ, වෙනස් කරන්නේ සහ අයින් කරන්නේ කොහොමද කියලා.
1. Create (දත්ත එකතු කිරීම)
අලුත් user කෙනෙක්ව database එකට එකතු කරන්න, අපි User
class එකෙන් object එකක් හදලා, ඒක db.session
එකට එකතු කරලා commit
කරනවා.
# app.py file eke nikanma add karanna puluwan natham python shell eken run karanna puluwan
# Terminal eke 'python' kiyala gahala shell eka open karaganna
# Ethana me commands eka by one run karanna
# Mulinma app eka run karala thiyenna one
# Flask shell ekak hadaganna nam, app.py file eke methana add karanna
@app.cli.command('create_test_user')
def create_test_user():
with app.app_context():
new_user = User(username='Amal', email='[email protected]')
db.session.add(new_user)
db.session.commit()
print(f"User {new_user.username} created with ID: {new_user.id}")
# Me command eka run karanna terminal eke:
# flask create_test_user
# No nattham, nikanම Python shell eke me widiyata karanna puluwan (debug mode off karala thiyanam, app.app_context() danne nathuwa run wenne ne):
# python
# from app import app, db, User
# with app.app_context():
# new_user = User(username='Kasun', email='[email protected]', active=True)
# db.session.add(new_user)
# db.session.commit()
# print(f"User created with ID: {new_user.id}")
මතක තියාගන්න, db.session
එක කියන්නේ database එකත් එක්ක කරන operations එකතුවක්. db.session.add()
වලින් object එක session එකට එකතු කරනවා, ඒත් database එකට save වෙන්නේ නැහැ. db.session.commit()
වලින් තමයි ඇත්තටම database එකට වෙනස්කම් save වෙන්නේ. Session එකක් ඇතුලේ මොකක් හරි වැරදුනොත් db.session.rollback()
වලින් කලින් තිබ්බ තත්වයට යන්න පුළුවන්.
2. Read (දත්ත කියවීම)
දැන් අපි බලමු database එකෙන් users ලා හොයාගන්නේ කොහොමද කියලා.
# All users la ganima
with app.app_context():
all_users = User.query.all()
print("All users:")
for user in all_users:
print(f"ID: {user.id}, Username: {user.username}, Email: {user.email}")
# ID eken user kenek ganima
with app.app_context():
user_by_id = User.query.get(1) # ID 1 wena user
if user_by_id:
print(f"\nUser with ID 1: {user_by_id.username}")
else:
print("\nUser with ID 1 not found.")
# Filter karala user kenek ganima (e.g., username eka 'Amal' wena kenawa)
with app.app_context():
user_by_username = User.query.filter_by(username='Amal').first() # first() danawa mulinma enna eka ganimata
if user_by_username:
print(f"\nUser with username Amal: {user_by_username.email}")
else:
print("\nUser with username Amal not found.")
# Multiple filters
with app.app_context():
active_users = User.query.filter_by(active=True).all()
print("\nActive users:")
for user in active_users:
print(user.username)
User.query
එක තමයි SQLAlchemy queries කරන්න පාවිච්චි කරන ආරම්භක ලක්ෂ්යය. .all()
, .get()
, .first()
, .filter_by()
වගේ දේවල් තමයි අපි දත්ත හොයන්න පාවිච්චි කරන්නේ.
3. Update (දත්ත යාවත්කාලීන කිරීම)
දැනට තියෙන user කෙනෙක්ගේ තොරතුරු වෙනස් කරමු.
with app.app_context():
user_to_update = User.query.get(1) # ID 1 wena user ganima
if user_to_update:
user_to_update.email = '[email protected]'
db.session.commit()
print(f"\nUser ID 1's email updated to: {user_to_update.email}")
else:
print("\nUser ID 1 not found for update.")
මේකෙදි අපි මුලින්ම update කරන්න ඕන object එක හොයාගන්නවා, ඊට පස්සේ ඒකේ attribute එක වෙනස් කරලා db.session.commit()
කරනවා.
4. Delete (දත්ත ඉවත් කිරීම)
දැන් අපි user කෙනෙක්ව database එකෙන් අයින් කරමු.
with app.app_context():
user_to_delete = User.query.get(1) # ID 1 wena user ganima
if user_to_delete:
db.session.delete(user_to_delete)
db.session.commit()
print(f"\nUser ID 1 ({user_to_delete.username}) deleted successfully.")
else:
print("\nUser ID 1 not found for deletion.")
# Delete karana user kenek hoyala balanna:
with app.app_context():
deleted_user = User.query.get(1)
if deleted_user is None:
print("User ID 1 is indeed deleted.")
අපි අයින් කරන්න ඕන object එක හොයාගෙන db.session.delete()
කරලා db.session.commit()
කරනවා.
පොදු ගැටළු සහ විසඳුම් (Troubleshooting and Best Practices)
Flask එක්ක SQLAlchemy පාවිච්චි කරනකොට එන්න පුළුවන් පොදු ගැටළු කීපයක් සහ ඒවට විසඳුම් වගේම හොඳම පුරුදු (best practices) කිහිපයක් ගැනත් දැනගනිමු.
1. RuntimeError: Application context not pushed.
මේ error එක ගොඩක් වෙලාවට එන්නේ ඔයා Flask application context එකක් නැතුව database operations කරන්න හදනකොට. Flask-SQLAlchemy වලට Flask app එකේ configuration එක දැනගන්න context එකක් අවශ්යයි. උදාහරණයක් විදිහට, ඔයා app.py
file එක run නොකර, වෙනම script එකකින් db.create_all()
කරන්න හැදුවොත් මේ error එක එන්න පුළුවන්.
විසඳුම: with app.app_context():
block එක ඇතුලේ database operations කරන්න. අපි උඩ කෝඩ් එකේ db.create_all()
කරපු විදිහටම.
from app import app, db, User # app.py eken import karagena
with app.app_context():
# Database operations goes here
# e.g., db.create_all(), User.query.all(), etc.
all_users = User.query.all()
print(all_users)
2. Session Management සහ PendingRollbackError
SQLAlchemy වලට session එකක් තියෙනවා. ඒ session එක ඇතුලේ කරන operations commit කරනකම් හෝ rollback කරනකම් pending තත්වයක තියෙන්න පුළුවන්. මොකක් හරි error එකක් ආවොත්, session එක corrupted වෙන්න පුළුවන්. එතකොට PendingRollbackError
වගේ error එකක් එන්න පුළුවන්.
විසඳුම: සෑම database operation එකකින් පස්සේ db.session.commit()
හෝ db.session.rollback()
කරන්න. try...except...finally
block එකක් පාවිච්චි කරන එක හොඳ පුරුද්දක්.
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
price = db.Column(db.Float, nullable=False)
def __repr__(self):
return f"<Product {self.name}>"
@app.route('/add_product')
def add_product():
try:
with app.app_context():
new_product = Product(name="Laptop", price=1200.00)
db.session.add(new_product)
db.session.commit()
return jsonify({'message': f'Product {new_product.name} added successfully!'})
except Exception as e:
db.session.rollback() # Error ekak awoth rollback karanna
return jsonify({'error': str(e)}), 500
finally:
db.session.close() # Operation eken passe session eka close karanna
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)
3. Database Migrations
ඔයාගේ application එක develop කරනකොට ඔයාගේ database models වලට අලුත් features එකතු වෙන්න පුළුවන්, නැත්නම් existing ones වෙනස් වෙන්න පුළුවන්. ඒ කියන්නේ database table structure එක වෙනස් වෙනවා. මේ වගේ වෙලාවට Database Migrations කියන එක ගොඩක් වැදගත් වෙනවා. Flask වලට Flask-Migrate කියන extension එක තියෙනවා, ඒක Alembic කියන tool එකෙන් වැඩ කරන්නේ.
උපදෙස්: production වලට යනකොට අනිවාර්යයෙන්ම Flask-Migrate වගේ migration tool එකක් පාවිච්චි කරන්න. ඒකෙන් ඔයාගේ database schema එක පහසුවෙන් update කරගන්න පුළුවන්.
4. Separate Database Logic
විශාල Flask applications වලදී, database interactions වලට අදාළ logic වෙනම modules වලට වෙන් කරන එක හොඳ පුරුද්දක්. උදාහරණයක් විදිහට, models.py
කියන file එකේ models definitions විතරක් තියන්න පුළුවන්, crud_operations.py
වගේ file එකක database manipulations වලට අදාළ functions තියන්න පුළුවන්.
නිගමනය (Conclusion)
ඉතින් යාළුවනේ, අපි මේ ලිපියෙන් Flask Framework එකේදී දත්ත ගබඩා එක්ක වැඩ කරන්න SQLAlchemy කියන බලගතු ORM එක පාවිච්චි කරන්නේ කොහොමද කියලා විස්තරාත්මකව ඉගෙන ගත්තා. අපි ORM concepts වලින් පටන් අරන්, Flask එක්ක SQLAlchemy set up කරගත්තා, අපේම models හදාගත්තා, සහ දත්ත එකතු කරන, කියවන, වෙනස් කරන, අයින් කරන (CRUD operations) හැටි practical examples එක්ක බැලුවා. ඒ වගේම පොදු ගැටළු වලට විසඳුම් සහ හොඳම පුරුදු ගැනත් දැනගත්තා.
දැන් ඔයාටම පුළුවන් ඔයාගේ Flask ඇප් එකකට දත්ත ගබඩාවක් සම්බන්ධ කරලා වැඩ කරන්න. මතක තියාගන්න, practice එක තමයි වැදගත්ම දේ. මේ දේවල් ඔයාගේ ඊළඟ project එකට යොදලා බලන්න. මොනවා හරි ප්රශ්න තියෙනවා නම්, ඔයාගේ අත්දැකීම් කොමෙන්ට් එකකින් පහතින් බෙදාගන්න. ඔයාලට සුභ අනාගතයක්!
ගිහින් එන්නම්, තවත් අලුත් දෙයක් එක්ක නැවත හමුවෙමු!