Simple and rapid application development framework, built on top of Flask, with detailed security, auto CRUD generation, and comprehensive UI components.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
SQLAlchemy integration with enhanced models, database interfaces, and application factory support providing flexible database management, model utilities, and seamless integration with Flask-AppBuilder's view and API systems.
Base SQLAlchemy model class that provides enhanced functionality and integration with Flask-AppBuilder's features including JSON serialization and table configuration.
from flask_appbuilder.models.sqla import Model
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey
from sqlalchemy.orm import relationship
import datetime
class Model(object):
"""
Base model class for all Flask-AppBuilder models.
Provides enhanced SQLAlchemy functionality.
"""
def to_json(self):
"""
Convert model instance to JSON-serializable dictionary.
Returns:
Dict with model data, handling relationships and special types
"""
# Base table configuration
__table_args__ = {"extend_existing": True}
# Usage example - Complete model definition
class Person(Model):
__tablename__ = 'persons'
# Primary key
id = Column(Integer, primary_key=True)
# Basic fields
name = Column(String(150), unique=True, nullable=False)
email = Column(String(120), unique=True, nullable=False)
phone = Column(String(20))
active = Column(Boolean, default=True)
# Timestamps
created_on = Column(DateTime, default=datetime.datetime.now)
updated_on = Column(DateTime, default=datetime.datetime.now,
onupdate=datetime.datetime.now)
# Foreign key relationship
department_id = Column(Integer, ForeignKey('departments.id'))
department = relationship("Department", back_populates="persons")
# String representation
def __repr__(self):
return self.name
# Custom JSON serialization
def to_json(self):
return {
'id': self.id,
'name': self.name,
'email': self.email,
'active': self.active,
'department': self.department.name if self.department else None,
'created_on': self.created_on.isoformat() if self.created_on else None
}
class Department(Model):
__tablename__ = 'departments'
id = Column(Integer, primary_key=True)
name = Column(String(100), unique=True, nullable=False)
description = Column(String(500))
# Reverse relationship
persons = relationship("Person", back_populates="department")
def __repr__(self):
return self.nameEnhanced Flask-SQLAlchemy class providing Flask-AppBuilder integration, application factory support, and advanced session management capabilities.
from flask_appbuilder.models.sqla import SQLA
from flask_sqlalchemy import SQLAlchemy
class SQLA(SQLAlchemy):
"""
Enhanced SQLAlchemy class with Flask-AppBuilder integration.
Supports application factory pattern and custom configurations.
"""
def make_declarative_base(self, model, metadata=None):
"""
Create declarative base class with Flask-AppBuilder Model.
Parameters:
- model: Base model class (Model)
- metadata: SQLAlchemy metadata instance
Returns:
Declarative base class
"""
def get_tables_for_bind(self, bind=None):
"""
Get tables for specific database bind.
Parameters:
- bind: Database bind key
Returns:
List of table objects for the bind
"""
def create_session(self, options):
"""
Create custom database session with options.
Parameters:
- options: Session configuration dict
Returns:
SQLAlchemy session instance
"""
# Application factory usage
from flask import Flask
from flask_appbuilder import AppBuilder
# Create SQLA instance
db = SQLA()
def create_app():
app = Flask(__name__)
# Configure database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Initialize SQLA with app
db.init_app(app)
# Initialize AppBuilder
appbuilder = AppBuilder(app, db.session)
return app
# Multiple database binds example
app.config['SQLALCHEMY_BINDS'] = {
'users': 'sqlite:///users.db',
'products': 'postgresql://user:pass@localhost/products'
}
class User(Model):
__bind_key__ = 'users'
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String(80), unique=True, nullable=False)
class Product(Model):
__bind_key__ = 'products'
__tablename__ = 'products'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)Backward compatibility alias for the Model class to support legacy Flask-AppBuilder applications.
from flask_appbuilder.models.sqla import Base
# Base is an alias for Model - both are equivalent
Base = Model
# Legacy usage (still supported)
class LegacyModel(Base):
__tablename__ = 'legacy_table'
id = Column(Integer, primary_key=True)
name = Column(String(100))
# Modern usage (recommended)
class ModernModel(Model):
__tablename__ = 'modern_table'
id = Column(Integer, primary_key=True)
name = Column(String(100))Data model interface providing abstraction layer between models and Flask-AppBuilder views/APIs for database operations.
from flask_appbuilder.models.sqla.interface import SQLAInterface
class SQLAInterface:
def __init__(self, obj, session=None):
"""
Initialize interface for SQLAlchemy model.
Parameters:
- obj: SQLAlchemy model class
- session: SQLAlchemy session (optional)
"""
def get_query(self, filters=None, order_column='', order_direction=''):
"""
Get SQLAlchemy query with filters and ordering.
Parameters:
- filters: List of filter objects
- order_column: Column name for ordering
- order_direction: 'asc' or 'desc'
Returns:
SQLAlchemy Query object
"""
def get_count(self, filters=None):
"""
Get count of records matching filters.
Parameters:
- filters: List of filter objects
Returns:
Integer count of matching records
"""
def get(self, pk):
"""
Get single record by primary key.
Parameters:
- pk: Primary key value
Returns:
Model instance or None
"""
def get_keys(self, lst):
"""
Get primary key values from list of model instances.
Parameters:
- lst: List of model instances
Returns:
List of primary key values
"""
def get_pk_value(self, item):
"""
Get primary key value from model instance.
Parameters:
- item: Model instance
Returns:
Primary key value
"""
def add(self, item):
"""
Add model instance to database.
Parameters:
- item: Model instance to add
Returns:
Added model instance
"""
def edit(self, item):
"""
Update model instance in database.
Parameters:
- item: Model instance to update
Returns:
Updated model instance
"""
def delete(self, item):
"""
Delete model instance from database.
Parameters:
- item: Model instance to delete
Returns:
Boolean success flag
"""
# Usage with views and APIs
from flask_appbuilder import ModelView, ModelRestApi
class PersonView(ModelView):
datamodel = SQLAInterface(Person)
list_columns = ['name', 'email', 'department']
class PersonApi(ModelRestApi):
datamodel = SQLAInterface(Person)
list_columns = ['id', 'name', 'email']
# Custom interface usage
interface = SQLAInterface(Person)
# Get all active persons
filters = [FilterEqual('active', True)]
query = interface.get_query(filters=filters, order_column='name')
persons = query.all()
# Get count
count = interface.get_count(filters=filters)
# CRUD operations
new_person = Person(name="John Doe", email="john@example.com")
interface.add(new_person)
person = interface.get(1)
person.email = "newemail@example.com"
interface.edit(person)
interface.delete(person)Filter classes for building complex database queries with type-safe operations and support for various data types.
from flask_appbuilder.models.filters import BaseFilter, FilterEqual, FilterNotEqual, \
FilterGreater, FilterSmaller, FilterStartsWith, FilterEndsWith, FilterContains, \
FilterNotStartsWith, FilterNotEndsWith, FilterNotContains, FilterEqualFunction, \
FilterInFunction, FilterConverter
# Basic filters
class FilterEqual(BaseFilter):
"""Exact match filter (column = value)"""
class FilterNotEqual(BaseFilter):
"""Not equal filter (column != value)"""
class FilterGreater(BaseFilter):
"""Greater than filter (column > value)"""
class FilterSmaller(BaseFilter):
"""Less than filter (column < value)"""
# String filters
class FilterStartsWith(BaseFilter):
"""Starts with filter (column LIKE 'value%')"""
class FilterEndsWith(BaseFilter):
"""Ends with filter (column LIKE '%value')"""
class FilterContains(BaseFilter):
"""Contains filter (column LIKE '%value%')"""
class FilterNotStartsWith(BaseFilter):
"""Does not start with filter"""
class FilterNotEndsWith(BaseFilter):
"""Does not end with filter"""
class FilterNotContains(BaseFilter):
"""Does not contain filter"""
# Function filters
class FilterEqualFunction(BaseFilter):
"""Filter using SQL function (FUNC(column) = value)"""
class FilterInFunction(BaseFilter):
"""Filter using IN with function"""
# Usage examples
from flask_appbuilder.models.sqla.filters import FilterEqual, FilterContains
# In ModelView or ModelRestApi
class PersonView(ModelView):
datamodel = SQLAInterface(Person)
# Base filters applied to all queries
base_filters = [
['active', FilterEqual, True], # active = True
['name', FilterContains, 'John'], # name LIKE '%John%'
['created_on', FilterGreater, datetime.date(2023, 1, 1)] # created_on > '2023-01-01'
]
# Available search filters
search_filters = {
'name': [FilterEqual, FilterContains, FilterStartsWith],
'email': [FilterEqual, FilterContains],
'active': [FilterEqual],
'created_on': [FilterEqual, FilterGreater, FilterSmaller]
}
# Custom filter example
class FilterActiveInLastDays(BaseFilter):
name = "Active in Last N Days"
arg_name = "days"
def apply(self, query, value):
cutoff_date = datetime.datetime.now() - datetime.timedelta(days=int(value))
return query.filter(self.column >= cutoff_date)
# Advanced filtering with relationships
class PersonView(ModelView):
datamodel = SQLAInterface(Person)
# Filter by related model fields
base_filters = [
['department.name', FilterEqual, 'Engineering'], # Join filter
['department.active', FilterEqual, True] # Related field filter
]Utility mixins and helper functions for common model patterns and enhanced functionality.
# Audit mixin for tracking changes
from flask_appbuilder.models.mixins import AuditMixin
from flask_appbuilder.models.decorators import renders
import datetime
class AuditMixin(object):
"""Mixin for audit trail fields."""
created_on = Column(DateTime, default=datetime.datetime.now, nullable=False)
changed_on = Column(DateTime, default=datetime.datetime.now,
onupdate=datetime.datetime.now, nullable=False)
created_by_fk = Column(Integer, ForeignKey('ab_user.id'), nullable=False)
changed_by_fk = Column(Integer, ForeignKey('ab_user.id'), nullable=False)
created_by = relationship("User", foreign_keys=[created_by_fk])
changed_by = relationship("User", foreign_keys=[changed_by_fk])
# File mixin for file uploads
class FileColumn(Model):
"""Model for file storage."""
id = Column(Integer, primary_key=True)
file = Column(FileColumn, nullable=False)
# Image mixin
class ImageColumn(Model):
"""Model for image storage."""
id = Column(Integer, primary_key=True)
image = Column(ImageColumn, nullable=False)
# Usage with audit mixin
class AuditedPerson(Model, AuditMixin):
__tablename__ = 'audited_persons'
id = Column(Integer, primary_key=True)
name = Column(String(150), nullable=False)
email = Column(String(120), nullable=False)
# Custom field rendering
@renders('name')
def render_name(self):
"""Custom rendering for name field."""
return f"<strong>{self.name}</strong>"
# Model validation
from marshmallow import ValidationError
class Person(Model):
__tablename__ = 'persons'
id = Column(Integer, primary_key=True)
email = Column(String(120), nullable=False)
def validate_email(self, email):
"""Custom email validation."""
if not email or '@' not in email:
raise ValidationError("Invalid email address")
# Soft delete mixin
class SoftDeleteMixin(object):
"""Mixin for soft delete functionality."""
deleted = Column(Boolean, default=False, nullable=False)
deleted_on = Column(DateTime)
def soft_delete(self):
"""Mark record as deleted."""
self.deleted = True
self.deleted_on = datetime.datetime.now()
class SoftDeletedModel(Model, SoftDeleteMixin):
__tablename__ = 'soft_deleted'
id = Column(Integer, primary_key=True)
name = Column(String(100))
# Override queries to exclude deleted records
@classmethod
def query_active(cls):
return cls.query.filter(cls.deleted == False)Install with Tessl CLI
npx tessl i tessl/pypi-flask-appbuilder