Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an Eve-aware base class (WIP) #180

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ library. This means that you can simply use something like that:

.. literalinclude:: ../eve_sqlalchemy/examples/simple/tables.py

We have used ``CommonColumns`` abstract class to provide attributes used by
We have used ``BaseModel`` abstract class to provide attributes used by
Eve, such as ``_created`` and ``_updated``. These are not needed if you are only
reading from the database. However, if your API is also writing to the database,
then you need to include them.
Expand Down
4 changes: 2 additions & 2 deletions docs/upgrading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ directory):

.. code-block:: python

class People(CommonColumns):
class People(BaseModel):
__tablename__ = 'people'
id = Column(Integer, primary_key=True, autoincrement=True)
firstname = Column(String(80))
lastname = Column(String(120))
fullname = column_property(firstname + " " + lastname)


class Invoices(CommonColumns):
class Invoices(BaseModel):
__tablename__ = 'invoices'
id = Column(Integer, primary_key=True, autoincrement=True)
number = Column(Integer)
Expand Down
15 changes: 15 additions & 0 deletions eve_sqlalchemy/declarative.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from sqlalchemy import Column, DateTime, String, func
from sqlalchemy.ext.declarative import declarative_base


class BaseModel(object):
"""
Master Eve model for SQLALchemy. It provides common columns such as
_created, _updated, and _etag.
"""
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now(), onupdate=func.now())
_etag = Column(String(40))


BaseModel = declarative_base(cls=BaseModel)
4 changes: 2 additions & 2 deletions eve_sqlalchemy/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from eve import ISSUES

from eve_sqlalchemy import SQL
from eve_sqlalchemy.tests.test_sql_tables import Base
from eve_sqlalchemy.declarative import BaseModel
from eve_sqlalchemy.validation import ValidatorSQL


Expand Down Expand Up @@ -47,7 +47,7 @@ def setUp(self, settings_file=None, url_converters=None,
if declarative_base is not None:
SQL.driver.Model = declarative_base
else:
SQL.driver.Model = Base
SQL.driver.Model = BaseModel

self.app = eve.Eve(settings=self.settings_file,
url_converters=url_converters, data=SQL,
Expand Down
8 changes: 3 additions & 5 deletions eve_sqlalchemy/tests/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from sqlalchemy import Column, DateTime, String, func
from sqlalchemy.ext.declarative import declared_attr

from eve_sqlalchemy.declarative import BaseModel


def call_for(*args):
def decorator(f):
Expand All @@ -14,11 +15,8 @@ def loop(self):
return decorator


class BaseModel(object):
class BaseModel(BaseModel):
__abstract__ = True
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now())
_etag = Column(String)

@declared_attr
def __tablename__(cls):
Expand Down
20 changes: 4 additions & 16 deletions eve_sqlalchemy/tests/integration/collection_class_set.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from sqlalchemy import (
Column, DateTime, ForeignKey, Integer, String, Table, func,
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey, Integer, Table
from sqlalchemy.orm import relationship

from eve_sqlalchemy.config import DomainConfig, ResourceConfig
from eve_sqlalchemy.declarative import BaseModel
from eve_sqlalchemy.tests import TestMinimal

Base = declarative_base()


class BaseModel(Base):
__abstract__ = True
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now(), onupdate=func.now())
_etag = Column(String(40))


association_table = Table(
'association', Base.metadata,
'association', BaseModel.metadata,
Column('left_id', Integer, ForeignKey('left.id')),
Column('right_id', Integer, ForeignKey('right.id'))
)
Expand Down Expand Up @@ -55,7 +43,7 @@ class TestCollectionClassSet(TestMinimal):

def setUp(self, url_converters=None):
super(TestCollectionClassSet, self).setUp(
SETTINGS, url_converters, Base)
SETTINGS, url_converters, BaseModel)

def bulk_insert(self):
self.app.data.insert('children', [{'id': k} for k in range(1, 5)])
Expand Down
16 changes: 4 additions & 12 deletions eve_sqlalchemy/tests/integration/get_none_values.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from sqlalchemy import Column, DateTime, Integer, String, func
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer

from eve_sqlalchemy.config import DomainConfig, ResourceConfig
from eve_sqlalchemy.declarative import BaseModel
from eve_sqlalchemy.tests import TestMinimal

Base = declarative_base()


class BaseModel(Base):
__abstract__ = True
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now(), onupdate=func.now())
_etag = Column(String(40))


class Node(BaseModel):
__tablename__ = 'node'
Expand All @@ -37,7 +28,8 @@ class Node(BaseModel):
class TestGetNoneValues(TestMinimal):

def setUp(self, url_converters=None):
super(TestGetNoneValues, self).setUp(SETTINGS, url_converters, Base)
super(TestGetNoneValues, self).setUp(SETTINGS, url_converters,
BaseModel)

def bulk_insert(self):
self.app.data.insert('nodes', [{'id': k} for k in range(1, 5)])
Expand Down
53 changes: 15 additions & 38 deletions eve_sqlalchemy/tests/test_sql_tables.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import hashlib

from sqlalchemy import (
Boolean, Column, DateTime, Float, ForeignKey, Integer, LargeBinary,
PickleType, String, Table, func,
PickleType, String, Table,
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

Base = declarative_base()


class CommonColumns(Base):
"""
Master SQLAlchemy Model. All the SQL tables defined for the application
should inherit from this class. It provides common columns such as
_created, _updated and _id.

WARNING: the _id column name does not respect Eve's setting for custom
ID_FIELD.
"""
__abstract__ = True
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now(), onupdate=func.now())
_etag = Column(String)

def __init__(self, *args, **kwargs):
h = hashlib.sha1()
self._etag = h.hexdigest()
super(CommonColumns, self).__init__(*args, **kwargs)
from eve_sqlalchemy.declarative import BaseModel


class DisabledBulk(CommonColumns):
class DisabledBulk(BaseModel):
__tablename__ = 'disabled_bulk'
_id = Column(Integer, primary_key=True)
string_field = Column(String(25))


InvoicingContacts = Table(
'invoicing_contacts', Base.metadata,
'invoicing_contacts', BaseModel.metadata,
Column('invoice_id', Integer, ForeignKey('invoices._id'),
primary_key=True),
Column('contact_id', Integer, ForeignKey('contacts._id'),
primary_key=True)
)


class Contacts(CommonColumns):
class Contacts(BaseModel):
__tablename__ = 'contacts'
_id = Column(Integer, primary_key=True)
ref = Column(String(25), unique=True, nullable=False)
Expand Down Expand Up @@ -81,7 +58,7 @@ class Contacts(CommonColumns):
abool = Column(Boolean)


class Invoices(CommonColumns):
class Invoices(BaseModel):
__tablename__ = 'invoices'
_id = Column(Integer, primary_key=True)
inv_number = Column(String(25))
Expand All @@ -90,66 +67,66 @@ class Invoices(CommonColumns):
invoicing_contacts = relationship('Contacts', secondary=InvoicingContacts)


class Empty(CommonColumns):
class Empty(BaseModel):
__tablename__ = 'empty'
_id = Column(Integer, primary_key=True)
inv_number = Column(String(25))


DepartmentsContacts = Table(
'department_contacts', Base.metadata,
'department_contacts', BaseModel.metadata,
Column('department_id', Integer, ForeignKey('departments._id'),
primary_key=True),
Column('contact_id', Integer, ForeignKey('contacts._id'),
primary_key=True)
)

CompaniesDepartments = Table(
'companies_departments', Base.metadata,
'companies_departments', BaseModel.metadata,
Column('company_id', Integer, ForeignKey('companies._id'),
primary_key=True),
Column('department_id', Integer, ForeignKey('departments._id'),
primary_key=True)
)


class Departments(CommonColumns):
class Departments(BaseModel):
__tablename__ = 'departments'
_id = Column(Integer, primary_key=True)
title = Column(String(25))
members = relationship('Contacts', secondary=DepartmentsContacts)


class Companies(CommonColumns):
class Companies(BaseModel):
__tablename__ = 'companies'
_id = Column(Integer, primary_key=True)
holding_id = Column(String(16), ForeignKey('companies._id'))
holding = relationship('Companies', remote_side=[_id])
departments = relationship('Departments', secondary=CompaniesDepartments)


class Payments(CommonColumns):
class Payments(BaseModel):
__tablename__ = 'payments'
_id = Column(Integer, primary_key=True)
a_string = Column(String(10))
a_number = Column(Integer)


class InternalTransactions(CommonColumns):
class InternalTransactions(BaseModel):
__tablename__ = 'internal_transactions'
_id = Column(Integer, primary_key=True)
internal_string = Column(String(10))
internal_number = Column(Integer)


class Login(CommonColumns):
class Login(BaseModel):
__tablename__ = 'login'
_id = Column(Integer, primary_key=True)
email = Column(String(255), nullable=False, unique=True)
password = Column(String(32), nullable=False)


class Products(CommonColumns):
class Products(BaseModel):
__tablename__ = 'products'
sku = Column(String(16), primary_key=True)
title = Column(String(32))
Expand Down