Frink¶
About¶
Frink is a super basic ORM-like thing for using RethinkDB in Flask, built on top of Schematics. It has built in compatibility with Flask-Security.
Warning
Frink is currently pre-alpha and extremely likely to change. However, it is stable enough in the Flask-Security datastore that you could probably use it to enable Flask-Security to work with RethinkDB.
Install¶
pip install frink
If you are contributing to the development of Frink, install it as an editable package from your own clone of the git repo. That way you can commit and push you edits.
git clone git@github.com:hactar-is/frink.git lib/frink
pip install -e lib/frink
Quickstart¶
Flask¶
Frink is designed to be used with the Application Factory pattern in Flask.
from frink.connection import RethinkDB
db = RethinkDB()
Then in your application factory, call init_app on the DB object.
def create_app():
...
db.init_app(app)
Flask-Security¶
Frink includes FrinkDatastore
and FrinkUserDatastore
for Flask-Security compatibility.
Define your User
and Role
models.
import datetime
from schematics.types.base import (
StringType, BooleanType, DateTimeType, IntType
)
from schematics.types.compound import (
ListType, ModelType
)
from flask.ext.security import UserMixin, RoleMixin
from frink.base import BaseModel
from frink.orm import ORMMeta
class Role(BaseModel, RoleMixin):
__metaclass__ = ORMMeta
name = StringType()
description = StringType()
class User(BaseModel, UserMixin):
__metaclass__ = ORMMeta
email = StringType()
password = StringType()
active = BooleanType(default=True)
confirmed_at = DateTimeType()
last_login_at = DateTimeType(default=datetime.datetime.now)
current_login_at = DateTimeType(default=datetime.datetime.now)
registered_at = DateTimeType()
last_login_ip = StringType()
current_login_ip = StringType()
login_count = IntType()
roles = ListType(ModelType(Role))
Then in your application factory, initialise this...
from frink.datastore import FrinkUserDatastore
from .users.models import User, Role
def create_app():
...
user_datastore = FrinkUserDatastore(db, User, Role)
security.init_app(app, user_datastore)
app.user_datastore = user_datastore
ORM¶
The ORM part of Frink gives you very basic querying abilities. For anything a little more complex you should probably just drop down to ReQL anyway.
Querying¶
Get a single instance by id.
User.query.get('9353b884-591b-404f-a4e2-30334d5ad335')
Get all instances.
User.query.all()
Get all instances, ordered and limited.
User.query.all(order_by='firstname', limit=10)
Filtering¶
Get a single instance, that is the first to match the filter.
User.query.first(firstname='Jeff')
Get a list of results matching kwargs filters.
User.query.filter(active=True, firstname='Jeff')
Order the results by firstname ascending.
User.query.filter(active=True, firstname='Jeff', order_by='<name')
Order the results by firstname descending.
User.query.filter(active=True, firstname='Jeff', order_by='>name')
Limit the results.
User.query.filter(active=True, firstname='Jeff', order_by='>name', limit=10)
Find all instances that match one column / value.
User.query.find_by(column='firstname', value='Jeff')
Ordered and limited.
User.query.find_by(column='firstname', value='Jeff', order_by='lastname', limit=1)
Get a single instance matched on column / value.
User.query.get_by(column='firstname', value='Jeff')
Todo
Add an offset
parameter to all methods that have a limit
argument for use with pagination.
ReQL¶
The models all contain references to the database and the table that they’re stored in, just in case you ever need to dynamically create a ReQL query. It’s also fairly useful even if you’re writing them by hand.
r.db(User._db).table(User._table).filter({"firstname": "Jeff"}).run(conn)
Contributing¶
If you think Frink could be useful for you, you could help get it to some kind of stability by getting involved. Contributors welcome.