Skip to content

Commit

Permalink
global: PostgreSQL Text type compatibility fix
Browse files Browse the repository at this point in the history
* BETTER Improves compatibility of Text fields  in PostrgeSQL by
  changing Text in models and removes Invenio hacks on MySQL Index and
  Primary Key creation because starting from SQLAlchemy>=1.0 it arises
  an exception if the length is specified. (addresses inveniosoftware#3037)

* Updates minimum Flask-Admin version to 1.1.0.

* PEP8/257 code style improvements.

Signed-off-by: Leonardo Rossi <[email protected]>
  • Loading branch information
Leonardo Rossi committed May 4, 2015
1 parent 020c210 commit 4a207c3
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 198 deletions.
83 changes: 3 additions & 80 deletions invenio/ext/sqlalchemy/engines/mysql.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2011, 2012, 2013, 2014 CERN.
# Copyright (C) 2011, 2012, 2013, 2014, 2015 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
Expand All @@ -21,86 +21,11 @@

import base64

# SQLAlchemy
import sqlalchemy

import sqlalchemy.types as types
from sqlalchemy import types as types
from sqlalchemy.ext.compiler import compiles

from sqlalchemy.schema import CreateIndex, PrimaryKeyConstraint


@compiles(CreateIndex, 'mysql')
def visit_create_index(element, compiler, **kw):
"""Return create index statement with defined length for text field.
example:
CREATE TABLE tableA
...
description TEXT(40)
...
INDEX ix_tableA_description ON (description(40))
"""
index = element.element
preparer = compiler.preparer
table = preparer.format_table(index.table)
name = preparer.quote(index.name, index.name.quote)

text = "ALTER TABLE %s ADD " % (table, )
if index.unique:
text += "UNIQUE "
text += "INDEX %s" % (name, )

lst = index.kwargs.get('mysql_length', None)

columns = []
for i, c in enumerate(index.columns):
cname = c.name
suffix = ''
if isinstance(lst, (list, tuple)) and len(lst) > i \
and lst[i] is not None:
suffix = '(%d)' % lst[i]
elif c.type != types.NULLTYPE \
and str(c.type).startswith('TEXT') \
and (c.type.length is not None):
suffix = '(%d)' % c.type.length
columns.append(cname + suffix)

text += '(' + ', '.join(columns) + ')'

if 'mysql_using' in index.kwargs:
using = index.kwargs['mysql_using']
if using is not None:
text += " USING %s" % (preparer.quote(using, index.quote))

return text


@compiles(PrimaryKeyConstraint, 'mysql')
def visit_primary_key_constraint(*element):
"""
Return create primary key constrains.
Return create primary key constrains with defined length
for text field.
"""
constraint, compiler = element
if len(constraint) == 0:
return ''
text = ""
if constraint.name is not None:
text += "CONSTRAINT %s " % \
compiler.preparer.format_constraint(constraint)
text += "PRIMARY KEY "
text += "(%s)" % ', '.join(c.name +
(c.type != types.NULLTYPE
and (str(c.type).startswith('TEXT')
and (c.type.length is not None))
and '(%d)' % c.type.length
or '')
for c in constraint)
text += compiler.define_constraint_deferrability(constraint)
return text
from sqlalchemy.types import TypeDecorator


@compiles(types.Text, 'sqlite')
Expand Down Expand Up @@ -140,8 +65,6 @@ def compile_largebinary(element, compiler, **kw):
"""Redefine LargeBinary filed type for MySQL."""
return 'LONGBLOB'

from sqlalchemy.types import TypeDecorator


class iBinary(TypeDecorator):

Expand Down
12 changes: 6 additions & 6 deletions invenio/modules/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@

from flask_login import current_user

from sqlalchemy.ext.hybrid import hybrid_property

from sqlalchemy_utils.types.choice import ChoiceType

from invenio.ext.passlib import password_context
from invenio.ext.passlib.hash import invenio_aes_encrypted_email
from invenio.ext.sqlalchemy import db

from sqlalchemy.ext.hybrid import hybrid_property

from sqlalchemy_utils.types.choice import ChoiceType

from .errors import AccountSecurityError, IntegrityUsergroupError
from .helpers import send_account_activation_email
from .signals import profile_updated
Expand Down Expand Up @@ -252,8 +252,8 @@ def __str__(self):
nullable=False, server_default='INTERNAL')

# FIXME Unique(login_method(70), name)
__table_args__ = (db.Index('login_method_name', login_method, name,
mysql_length=[60, None]),
__table_args__ = (db.Index('login_method_name', 'login_method', 'name',
mysql_length={'login_method': 60, 'name': 255}),
db.Model.__table_args__)

@classmethod
Expand Down
123 changes: 67 additions & 56 deletions invenio/modules/baskets/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2011, 2012 CERN.
# Copyright (C) 2011, 2012, 2015 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
Expand All @@ -17,154 +17,165 @@
# along with Invenio; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""
webbasket database models.
"""
"""webbasket database models."""

# General imports.
from invenio.ext.sqlalchemy import db

# Create your models here.

from invenio.modules.accounts.models import User, Usergroup
from invenio.modules.collections.models import Collection


class BskBASKET(db.Model):

"""Represents a BskBASKET record."""

__tablename__ = 'bskBASKET'
id = db.Column(db.Integer(15, unsigned=True), nullable=False,
primary_key=True)
id_owner = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(User.id), nullable=False, server_default='0')
primary_key=True)
id_owner = db.Column(
db.Integer(15, unsigned=True),
db.ForeignKey(User.id), nullable=False, server_default='0')
name = db.Column(db.String(50), nullable=False, server_default='',
index=True)
index=True)
date_modification = db.Column(db.DateTime, nullable=False,
server_default='1900-01-01 00:00:00')
server_default='1900-01-01 00:00:00')
nb_views = db.Column(db.Integer(15), nullable=False,
server_default='0')
server_default='0')
owner = db.relationship(User, backref='baskets')


class BskEXTREC(db.Model):

"""Represents a BskEXTREC record."""

__tablename__ = 'bskEXTREC'
id = db.Column(db.Integer(15, unsigned=True), nullable=False,
primary_key=True)
primary_key=True)
external_id = db.Column(db.Integer(15), nullable=False,
server_default='0')
server_default='0')
collection_id = db.Column(db.MediumInteger(9, unsigned=True),
db.ForeignKey(Collection.id), nullable=False,
server_default='0')
db.ForeignKey(Collection.id), nullable=False,
server_default='0')
original_url = db.Column(db.Text, nullable=True)
creation_date = db.Column(db.DateTime, nullable=False,
server_default='1900-01-01 00:00:00')
server_default='1900-01-01 00:00:00')
modification_date = db.Column(db.DateTime, nullable=False,
server_default='1900-01-01 00:00:00')
server_default='1900-01-01 00:00:00')
collection = db.relationship(Collection, backref='EXTRECs')


class BskEXTFMT(db.Model):

"""Represents a BskEXTFMT record."""

__tablename__ = 'bskEXTFMT'
id = db.Column(db.Integer(15, unsigned=True), nullable=False,
primary_key=True)
primary_key=True)
id_bskEXTREC = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(BskEXTREC.id), nullable=False,
server_default='0')
db.ForeignKey(BskEXTREC.id), nullable=False,
server_default='0')
format = db.Column(db.String(10), nullable=False, index=True,
server_default='')
server_default='')
last_updated = db.Column(db.DateTime, nullable=False,
server_default='1900-01-01 00:00:00')
server_default='1900-01-01 00:00:00')
value = db.Column(db.iLargeBinary, nullable=True)
EXTREC = db.relationship(BskEXTREC, backref='EXTFMTs')


class BskREC(db.Model):

"""Represents a BskREC record."""

__tablename__ = 'bskREC'
id_bibrec_or_bskEXTREC = db.Column(db.Integer(16), nullable=False,
server_default='0', primary_key=True, index=True)
id_bibrec_or_bskEXTREC = db.Column(
db.Integer(16), nullable=False,
server_default='0', primary_key=True, index=True)
id_bskBASKET = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0', primary_key=True)
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0', primary_key=True)
id_user_who_added_item = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(User.id),
nullable=False, server_default='0')
db.ForeignKey(User.id),
nullable=False, server_default='0')
score = db.Column(db.Integer(15), nullable=False,
server_default='0')
server_default='0')
date_added = db.Column(db.DateTime, nullable=False, index=True,
server_default='1900-01-01 00:00:00')
server_default='1900-01-01 00:00:00')
basket = db.relationship(BskBASKET, backref='RECs')
user_who_added_item = db.relationship(User)


class BskRECORDCOMMENT(db.Model):

"""Represents a BskRECORDCOMMENT record."""

__tablename__ = 'bskRECORDCOMMENT'
id = db.Column(db.Integer(15, unsigned=True), nullable=False,
primary_key=True, autoincrement=True)
primary_key=True, autoincrement=True)
id_bibrec_or_bskEXTREC = db.Column(db.Integer(16), nullable=False,
server_default='0')
server_default='0')
id_bskBASKET = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0')
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0')
id_user = db.Column(db.Integer(15, unsigned=True), db.ForeignKey(User.id),
nullable=False, server_default='0')
nullable=False, server_default='0')
title = db.Column(db.String(255), nullable=False,
server_default='')
server_default='')
body = db.Column(db.Text, nullable=False)
date_creation = db.Column(db.DateTime, nullable=False,
server_default='1900-01-01 00:00:00', index=True)
server_default='1900-01-01 00:00:00', index=True)
priority = db.Column(db.Integer(15), nullable=False,
server_default='0')
in_reply_to_id_bskRECORDCOMMENT = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(id), nullable=False, server_default='0')
server_default='0')
in_reply_to_id_bskRECORDCOMMENT = db.Column(
db.Integer(15, unsigned=True),
db.ForeignKey(id), nullable=False, server_default='0')
reply_order_cached_data = db.Column(db.Binary, nullable=True)
in_reply_to = db.relationship('BskRECORDCOMMENT')
basket = db.relationship(BskBASKET, backref='RECORDCOMMENTs')
user = db.relationship(User)

__table_args__ = (db.Index('bskRECORDCOMMENT_reply_order_cached_data',
reply_order_cached_data, mysql_length=[40]),
reply_order_cached_data, mysql_length=40),
db.Model.__table_args__)


class UserBskBASKET(db.Model):

"""Represents a UserBskBASKET record."""

__tablename__ = 'user_bskBASKET'
id_user = db.Column(db.Integer(15, unsigned=True), db.ForeignKey(User.id),
nullable=False, server_default='0', primary_key=True)
nullable=False, server_default='0', primary_key=True)
id_bskBASKET = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0', primary_key=True)
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0', primary_key=True)
topic = db.Column(db.String(50), nullable=False, server_default='')
user = db.relationship(User, backref='user_baskets')
user_basket = db.relationship(BskBASKET, backref='users')


class UsergroupBskBASKET(db.Model):

"""Represents a UsergroupBskBASKET record."""

__tablename__ = 'usergroup_bskBASKET'
id_usergroup = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(Usergroup.id), nullable=False,
server_default='0', primary_key=True)
db.ForeignKey(Usergroup.id), nullable=False,
server_default='0', primary_key=True)
id_bskBASKET = db.Column(db.Integer(15, unsigned=True),
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0', primary_key=True)
db.ForeignKey(BskBASKET.id), nullable=False,
server_default='0', primary_key=True)
topic = db.Column(db.String(50), nullable=False,
server_default='')
server_default='')
date_shared = db.Column(db.DateTime, nullable=False,
server_default='1900-01-01 00:00:00')
server_default='1900-01-01 00:00:00')
share_level = db.Column(db.Char(2), nullable=False, server_default='')
usergroup = db.relationship(Usergroup, backref='usergroup_baskets')
usergroup_basket = db.relationship(BskBASKET, backref='usergroups')



__all__ = ['BskBASKET',
__all__ = ('BskBASKET',
'BskEXTREC',
'BskEXTFMT',
'BskREC',
'BskRECORDCOMMENT',
'UserBskBASKET',
'UsergroupBskBASKET']
'UsergroupBskBASKET')
Loading

0 comments on commit 4a207c3

Please sign in to comment.