SQLAlachemy
Table of Contents
Reference
Column
# use a type with arguments
Column('data', String(50))
# use no arguments
Column('level', Integer)
# turn on autoincrement for this column despite
# the ForeignKey()
Column('id', ForeignKey('other.id'),
primary_key=True, autoincrement='ignore_fk')
- columnproperty can be used for column level options:
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
firstname = Column(String(50))
lastname = Column(String(50))
fullname = column_property(firstname + " " + lastname)
Column
can have positional arugments of SchemaItem, such asConstraint
,ForeignKey
,Sequence
, etc.
String, Text
# will assume that input is to be passed as Python unicode objects,
# and results returned as Python unicode objects
# There is an engine configuration which sets this flag to True by default.
String(convert_unicode=True)
Float
- For mysql, set
precision
to53
cause to make the column as double
Declarative API
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class SomeClass(Base):
__tablename__ = 'some_table'
id = Column(Integer, primary_key=True)
name = Column(String(50))
functions
Query
Session
Session.begin()
returns a SessionTransaction
object:
class SessionTransaction(object):
# ...
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self._assert_active(deactive_ok=True, prepared_ok=True)
if self.session.transaction is None:
return
if type is None:
try:
self.commit()
except:
with util.safe_reraise():
self.rollback()
else:
self.rollback()
So, we can use like this (code from here):
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
with session.begin():
item1 = session.query(Item).get(1)
item2 = session.query(Item).get(2)
item1.foo = 'bar'
item2.bar = 'foo'
Session.begin()
- Session.begin
- SessionTransaction.exit
- Returns
SessionTransaction
. It implements__exit__
, which callssession.commit
when levaving the block.
Session.commit() vs Session.flush()
- A Session object is basically an ongoing transaction of changes to a database
session.commit()
commits (persists) those changes to the database.flush()
is always called as part of a call tocommit()
s = Session()
# The Foo('A') object has been added to the session.
# It has not been committed to the database yet,
# but is returned as part of a query.
s.add(Foo('A'))
print s.query(Foo).all() # Output: [<Foo('A')>]
s.commit()
s2 = Session()
s2.autoflush = False
# The Foo('B') object is *not* returned as part of this query
# because it hasn't been flushed yet.
s2.add(Foo('B'))
print s2.query(Foo).all() # Output: [<Foo('A')>]
# Now, Foo('B') is in the same state as Foo('A') was above.
s2.flush()
print s2.query(Foo).all() # Output: [<Foo('A')>, <Foo('B')>]
# Foo('B') has not been committed, and rolling
# back the session's transaction removes it from the session.
s2.rollback()
print s2.query(Foo).all() # Output: [<Foo('A')>]
scopedsession
scoped_session
is used for ensuring onesession
for a scopescoped_session
usessessionmaker
- For
scopefunc
,threading.local()
is used by default. - Can be used like
Session
, by dynamic things.
hybridproperty
from sqlalchemy.ext.hybrid import hybrid_property
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
firstname = Column(String(50))
lastname = Column(String(50))
@hybrid_property
def fullname(self):
return self.firstname + " " + self.lastname
Can use fullname
like other columns:
How-to
Prefix all tables under a declarativebase
- Overriding both
cls.__tablename__
along withdict_['__tablename__']
is required becauseDeclarativeMeta
refers the attributes ofcls
during initialization.
from sqlalchemy.ext.declarative.api import DeclarativeMeta
class PrefixerMeta(DeclarativeMeta):
def __init__(cls, name, bases, dict_):
if '__tablename__' in dict_:
cls.__tablename__ = dict_['__tablename__'] = \
'someprefix_' + dict_['__tablename__']
return super().__init__(name, bases, dict_)
Base = declarative_base(metaclass=PrefixerMeta)
class SomeModel(Base):
__tablename__ = 'sometable'
...