Source code for backend.database.relationships
import inspect
from flask_sqlalchemy.model import camel_to_snake_case
from backend.extensions import db
from .column import Column
# RELATIONSHIP DOCS
# http://docs.sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html#relationship-patterns
# http://docs.sqlalchemy.org/en/rel_1_1/orm/backref.html#relationships-backref
# http://flask-sqlalchemy.pocoo.org/2.2/models/#one-to-many-relationships
# http://flask-sqlalchemy.pocoo.org/2.2/models/#many-to-many-relationships
# a bit of hackery to make type-hinting in PyCharm work correctly
from sqlalchemy.orm.relationships import RelationshipProperty
class __relationship_type_hinter__(RelationshipProperty):
# implement __call__ to silence the silly "not callable" warning
def __call__(self, *args, **kwargs):
pass
# alias common names
backref = db.backref # type: __relationship_type_hinter__
relationship = db.relationship # type: __relationship_type_hinter__
[docs]def foreign_key(model_or_table_name, fk_col=None, primary_key=False, **kwargs):
"""Helper method to add a foreign key Column to a model.
For example::
class Post(Model):
category_id = foreign_key('Category')
category = relationship('Category', back_populates='posts')
Is equivalent to::
class Post(Model):
category_id = Column(BigInteger, ForeignKey('category.id'), nullable=False)
category = relationship('Category', back_populates='posts')
:param model_or_table_name: the model or table name to link to
If given a lowercase string, it's treated as an explicit table name.
If there are any uppercase characters, it's assumed to be a model name,
and will be converted to snake case using the same automatic conversion
as Flask-SQLAlchemy does itself.
If given an instance of :class:`flask_sqlalchemy.Model`, use its
:attr:`__tablename__` attribute.
:param str fk_col: column name of the primary key (defaults to "id")
:param bool primary_key: Whether or not this Column is a primary key
:param dict kwargs: any other kwargs to pass the Column constructor
"""
model = model_or_table_name
table_name = model_or_table_name
fk_col = fk_col or 'id'
if inspect.isclass(model) and issubclass(model, db.Model):
table_name = model_or_table_name.__tablename__
elif table_name != table_name.lower():
table_name = camel_to_snake_case(table_name)
return Column(db.BigInteger,
db.ForeignKey(f'{table_name}.{fk_col}'),
primary_key=primary_key,
**kwargs)