If you are using SQLAlchemy then no doubt you’ve ran into some questions. Find below some more common usages.
Installation:
- pip install flask-sqlalchemy && pip freeze > requirements.txt
Table Definition:
You will notice that we are creating a unique constraint, primary keys, foreign keys.
- from sqlalchemy.orm import relationship
- from sqlalchemy.dialects.postgresql import BOOLEAN, BIT, DATE, JSON, DOUBLE_PRECISION, UUID
- from sqlalchemy.sql.functions import current_timestamp
- from sqlalchemy.schema import UniqueConstraint
- class MyTable(db.Model):
- __tablename__ = 'mytable'
- __table_args__ = (UniqueConstraint('column_name'),)
- primarykey_id = db.Column(db.Integer, primary_key=True, autoincrement="True")
- bit_column = db.Column(BIT)
- text_column = db.Column(db.Text)
- foreignkey_id = db.Column(db.Integer, db.ForeignKey('table.column'))
- foreignkey = relationship("table", foreign_keys=[foreignkey_id ])
- bool_column = db.Column(BOOLEAN)
- created_date = db.Column(db.DateTime, default=current_timestamp())
- guid_column = db.Column(UUID)
- bigint_column = db.Column(db.BigInteger)
- double_precision_column = db.Column(DOUBLE_PRECISION)
- json_column = db.Column(JSON)
- string_column = db.Column(db.String(200))
- def __init__(self, primarykey_id, bit_column):
- self.primarykey_id = primarykey_id
- self.bit_column = bit_column
- def __repr__(self):
- return '<MyTable primarykey_id %r Name %r bit_column %r>' % (self.primarykey_id, self.bit_column)
Database Connections:
The default connection is the “SQLALCHEMY_DATABASE_URI”. However you can attach to other DB by using the BINDS as demonstrated below.
- SQLALCHEMY_DATABASE_URI = "postgresql://##USER##:##PASS##@##SERVER##/##DB##"
- SQLALCHEMY_BINDS = {
- "NAME": "postgresql://##USER##:##PASS##@##SERVER##/##DB##",
- }
- b.session().execute("", params=dict(), bind=db.get_engine(app, 'NAME'))
Concatenation:
- from sqlalchemy.sql.expression import func
- func.concat(Table.Column,'-',Table.Column2)
Case Statements:
- from sqlalchemy.sql.expression import case
- case([(column1 == 'some_val', 1)], else_=0)
Ordering:
The example below does multiple columns but you can do just one if need be.
- order_by(Table.Column1.desc(), Table.Column2.asc())
Literals:
If you want to add NULL as a column output you must use literals. You could do this with a numerical data or string or whatever.
- from sqlalchemy import literal
- literal(None).label('column_name')
Retrieving Records:
- .first()
- .one()
- .fetchone()
- .all()
- .fetchall()
Joins:
- join(Table2, and_(Table2.column_id==Table1.column_id))
- outerjoin(Table2, and_(Table2.column_id==Table1.column_id))
Union:
- query1.union(query2)
Select Fields:
This just selects one column but you can comma separate it.
- .with_entities(Table.Column)
Where:
You don’t have to use and_ or or_. Use them as needed.
- from sqlalchemy.sql.expression import and_, or_
- .filter(and_(Table.Column1, Table.Column2, or_(Table.Column3_, Table.Column4))))
Not:
Select data where value is not NULL
- Table.Column.isnot(None)
Coalesce:
- from sqlalchemy.sql.functions import coalesce
- coalesce(Table.Column, 'Unknown')
Sum:
- from sqlalchemy.sql.expression import func
- func.sum(Table.Column)
Count:
- from sqlalchemy.sql.expression import func
- func.count()
- func.count('*')
Max:
- from sqlalchemy.sql.expression import func
- func.max(Table.Column)
AVG:
- from sqlalchemy.sql.expression import func
- func.avg(Table.Column)
Substring:
- from sqlalchemy.sql.expression import func
- func.substring(Table.Column, REGEX)
Like:
- Table.Column.like("value")
Not Like:
- from sqlalchemy.sql.expression import not_
- not_(Table.Column.like("value"))
Commit & Rollback:
- #commit
- session.commit()
- #rollback
- session.rollback()
Inline SQL:
- .execute('SELECT * FROM SP(:param)', params=dict(param=1))
Cast:
- from sqlalchemy.sql.functions import Cast
- Cast(Table.Column, BIT)
Array with Distinct:
- from sqlalchemy.sql.expression import distinct, func
- func.array_agg(distinct(Table.Column)).label('column_name')