Skip to content

Commit ce7040f

Browse files
committed
upgrade flask-sqlalchemy
1 parent a3a47ce commit ce7040f

2 files changed

Lines changed: 41 additions & 77 deletions

File tree

sopy/__init__.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import logging
22
import os
33
import sys
4+
45
import pkg_resources
5-
from flask import Flask, send_from_directory
6-
from flask import render_template, url_for, redirect
7-
from flask_alembic import Alembic
6+
from flask import (
7+
Flask, render_template, send_from_directory, redirect, url_for
8+
)
89
from flask_alembic.cli.click import cli as alembic_cli
910
from flask_babel import Babel
10-
from sopy.ext.sqlalchemy import SQLAlchemy
11+
12+
from sopy.ext.sqlalchemy import db
1113

1214
__version__ = pkg_resources.get_distribution('sopy').version
1315

14-
alembic = Alembic()
1516
babel = Babel()
16-
db = SQLAlchemy()
1717

1818

1919
def create_app(info=None):
@@ -26,15 +26,17 @@ def create_app(info=None):
2626
app.jinja_env.trim_blocks = True
2727
app.jinja_env.lstrip_blocks = True
2828

29-
alembic.init_app(app)
3029
babel.init_app(app)
3130
db.init_app(app)
3231

3332
from sopy.ext import views
3433

3534
views.init_app(app)
3635

37-
from sopy import auth, tags, se_data, canon, salad, wiki, pages, admin, transcript, spoiler
36+
from sopy import (
37+
auth, tags, se_data, canon, salad, wiki, pages, admin, transcript,
38+
spoiler
39+
)
3840

3941
app.register_blueprint(auth.bp, url_prefix='/auth')
4042
app.register_blueprint(tags.bp, url_prefix='/tags')
@@ -51,8 +53,14 @@ def create_app(info=None):
5153
def index():
5254
return render_template('index.html')
5355

54-
app.add_url_rule('/favicon.ico', None, app.send_static_file, defaults={'filename': 'favicon.ico'})
55-
app.add_url_rule('/robots.txt', None, app.send_static_file, defaults={'filename': 'robots.txt'})
56+
app.add_url_rule(
57+
'/favicon.ico', None, app.send_static_file,
58+
defaults={'filename': 'favicon.ico'}
59+
)
60+
app.add_url_rule(
61+
'/robots.txt', None, app.send_static_file,
62+
defaults={'filename': 'robots.txt'}
63+
)
5664

5765
@app.errorhandler(403)
5866
def forbidden(e):

sopy/ext/sqlalchemy.py

Lines changed: 23 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
from 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
55
from 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-
10764
class 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

Comments
 (0)