11from flask import current_app , g
2- from flask_sqlalchemy import SQLAlchemy as BaseSQLAlchemy , _camelcase_re , _QueryProperty , BaseQuery
3- from sqlalchemy import inspect , MetaData
4- from sqlalchemy . ext . declarative import DeclarativeMeta as BaseDeclarativeMeta , declared_attr , declarative_base
2+ from flask_alembic import Alembic
3+ from flask_sqlalchemy import Model as BaseModel , SQLAlchemy as BaseSQLAlchemy
4+ from sqlalchemy import MetaData , inspect
55from sqlalchemy .orm import was_deleted
66
77
8- class EqMixin :
9- """Compare and hash objects by custom values."""
10-
8+ class Model (BaseModel ):
119 def compare_value (self ):
1210 """Return what will be used to compare instances."""
13-
14- return inspect (type (self )).identity
11+ return inspect (self ).identity
1512
1613 def __eq__ (self , other ):
1714 """Instances of same class with equal compare values are equal."""
18-
1915 if not isinstance (other , self .__class__ ):
2016 return NotImplemented
2117
@@ -31,22 +27,19 @@ def __ne__(self, other):
3127
3228 def __hash__ (self ):
3329 """Composite hash of class and compare value."""
34-
3530 return hash (self .__class__ ) ^ hash (self .compare_value ())
3631
37-
38- class UniqueMixin :
39- """Keep a cache of unique instances in memory so new instances can be safely created in bulk before they are committed."""
40-
4132 @classmethod
4233 def create_unique (cls , session , ** kwargs ):
4334 o = cls (** kwargs )
4435 session .add (o )
4536 return o
4637
47-
4838 @classmethod
4939 def get_unique (cls , ** kwargs ):
40+ """Keep a cache of unique instances in memory so new instances
41+ can be safely created in bulk before they are committed.
42+ """
5043 g ._unique_cache = cache = getattr (g , '_unique_cache' , {})
5144 key = (cls , tuple (kwargs .items ()))
5245 o = cache .get (key )
@@ -68,61 +61,24 @@ def get_unique(cls, **kwargs):
6861 return o
6962
7063
71- class DeclarativeMeta (BaseDeclarativeMeta ):
72- def __init__ (cls , name , bases , attrs ):
73- """Handle Flask-SQLAlchemy's bind_key without setting tablename."""
74-
75- bind_key = attrs .pop ('__bind_key__' , None )
76- BaseDeclarativeMeta .__init__ (cls , name , bases , attrs )
77-
78- if bind_key is not None :
79- cls .__table__ .info ['bind_key' ] = bind_key
80-
81-
82- class Model (UniqueMixin , EqMixin ):
83- query_class = BaseQuery
84-
85- @declared_attr
86- def __tablename__ (cls ):
87- def _join (match ):
88- word = match .group ()
89-
90- if len (word ) > 1 :
91- return ('_%s_%s' % (word [:- 1 ], word [- 1 ])).lower ()
92-
93- return '_' + word .lower ()
94-
95- return _camelcase_re .sub (_join , cls .__name__ ).lstrip ('_' )
96-
97- def __str__ (self ):
98- return str (inspect (self ).identity )
99-
100- def __repr__ (self ):
101- return '<{0} {1}>' .format (self .__class__ .__name__ , self )
102-
103- def compare_value (self ):
104- return inspect (self ).identity
105-
106-
10764class SQLAlchemy (BaseSQLAlchemy ):
108- def __init__ (self , app = None , model = Model , meta = DeclarativeMeta , ** kwargs ):
109- self .BaseModel = model
110- self .DeclarativeMeta = meta
111- super (SQLAlchemy , self ).__init__ (app , ** kwargs )
65+ def __init__ (self , ** kwargs ):
66+ super ().__init__ (** kwargs )
67+ self .alembic = Alembic ()
11268
11369 def init_app (self , app ):
11470 super (SQLAlchemy , self ).init_app (app )
71+ self .alembic .init_app (app )
11572 app .shell_context_processor (lambda : {'db' : self })
11673
117- def make_declarative_base (self , metadata = None ):
118- metadata = MetaData (naming_convention = {
119- 'pk' : 'pk_%(table_name)s' ,
120- 'fk' : 'fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s' ,
121- 'uq' : 'uq_%(table_name)s_%(column_0_name)s' ,
122- 'ix' : 'ix_%(table_name)s_%(column_0_name)s' ,
123- 'ck' : 'ck_%(table_name)s_%(constraint_name)s' ,
124- })
125- base = declarative_base (metadata = metadata , cls = self .BaseModel , name = 'Model' , metaclass = self .DeclarativeMeta )
126- base .query = _QueryProperty (self )
127- base .db = self
128- return base
74+
75+ db = SQLAlchemy (
76+ metadata = MetaData (naming_convention = {
77+ 'pk' : 'pk_%(table_name)s' ,
78+ 'fk' : 'fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s' ,
79+ 'uq' : 'uq_%(table_name)s_%(column_0_name)s' ,
80+ 'ix' : 'ix_%(table_name)s_%(column_0_name)s' ,
81+ 'ck' : 'ck_%(table_name)s_%(constraint_name)s' ,
82+ }),
83+ model_class = Model
84+ )
0 commit comments