Skip to content

Commit

Permalink
Merge branch 'fix-where-relations'
Browse files Browse the repository at this point in the history
  • Loading branch information
dkellner committed Aug 5, 2018
2 parents 1064d84 + e73172d commit 916628e
Show file tree
Hide file tree
Showing 35 changed files with 145 additions and 41 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
.ropeproject

# Eve
run.py
settings.py
/run.py
/settings.py

# Python
*.py[co]
Expand Down
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
0.6.0 (unreleased)
~~~~~~~~~~~~~~~~~~

- Fix querying of list relations using `where` [Dominik Kellner]
- Update Tutorial (#177) [Nicola Iarocci]
- Return None-values again (#155) [Cuong Manh Le]
- Allow to supply own Flask-SQLAlchemy driver (#86) [fubu]
Expand Down
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ include AUTHORS CHANGES CONTRIBUTING.rst LICENSE
include requirements.txt tox.ini
graft docs
prune docs/_build
graft examples

global-exclude __pycache__ *.pyc *.pyo
2 changes: 1 addition & 1 deletion docs/trivial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Simple example

Create a file, called trivial.py, and include the following:

.. literalinclude:: ../examples/trivial/trivial.py
.. literalinclude:: ../eve_sqlalchemy/examples/trivial/trivial.py

Run this command to start the server:

Expand Down
4 changes: 2 additions & 2 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The main goal of the `SQLAlchemy`_ integration in Eve is to separate
dependencies and keep model registration depend only on sqlalchemy
library. This means that you can simply use something like that:

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

We have used ``CommonColumns`` abstract class to provide attributes used by
Eve, such as ``_created`` and ``_updated``. These are not needed if you are only
Expand All @@ -24,7 +24,7 @@ All standard Eve settings will work with `SQLAlchemy`_ support. However, you
need manually decide which `SQLAlchemy`_ declarative classes you wish to
register. You can do it using ``DomainConfig`` and ``ResourceConfig``:

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


Authentication example
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from eve import Eve

from eve_sqlalchemy import SQL
from eve_sqlalchemy.examples.foreign_primary_key.domain import Base, Lock, Node
from eve_sqlalchemy.validation import ValidatorSQL

from foreign_primary_key.domain import Base, Lock, Node

app = Eve(validator=ValidatorSQL, data=SQL)

db = app.data.driver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from eve_sqlalchemy.config import DomainConfig, ResourceConfig

from foreign_primary_key.domain import Lock, Node
from eve_sqlalchemy.examples.foreign_primary_key.domain import Lock, Node

DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite://'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from eve import Eve

from eve_sqlalchemy import SQL
from eve_sqlalchemy.examples.many_to_many.domain import Base, Child, Parent
from eve_sqlalchemy.validation import ValidatorSQL

from many_to_many.domain import Base, Child, Parent

app = Eve(validator=ValidatorSQL, data=SQL)

db = app.data.driver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from eve_sqlalchemy.config import DomainConfig, ResourceConfig

from many_to_many.domain import Child, Parent
from eve_sqlalchemy.examples.many_to_many.domain import Child, Parent

DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite://'
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from eve import Eve

from eve_sqlalchemy import SQL
from eve_sqlalchemy.examples.many_to_one.domain import Base, Child, Parent
from eve_sqlalchemy.validation import ValidatorSQL

from many_to_one.domain import Base, Child, Parent

app = Eve(validator=ValidatorSQL, data=SQL)

db = app.data.driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Parent(BaseModel):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
child_id = Column(Integer, ForeignKey('child.id'))
child = relationship("Child")
child = relationship("Child", backref="parents")


class Child(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from eve_sqlalchemy.config import DomainConfig, ResourceConfig

from many_to_one.domain import Child, Parent
from eve_sqlalchemy.examples.many_to_one.domain import Child, Parent

DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite://'
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from eve import Eve

from eve_sqlalchemy import SQL
from eve_sqlalchemy.examples.one_to_many.domain import Base, Child, Parent
from eve_sqlalchemy.validation import ValidatorSQL

from one_to_many.domain import Base, Child, Parent

app = Eve(validator=ValidatorSQL, data=SQL)

db = app.data.driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class BaseModel(Base):
class Parent(BaseModel):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child")
children = relationship("Child", backref="parent")


class Child(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from eve_sqlalchemy.config import DomainConfig, ResourceConfig

from one_to_many.domain import Child, Parent
from eve_sqlalchemy.examples.one_to_many.domain import Child, Parent

DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite://'
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from eve import Eve

from eve_sqlalchemy import SQL
from eve_sqlalchemy.examples.simple.tables import Base, Invoices, People
from eve_sqlalchemy.validation import ValidatorSQL

from simple.tables import Base, Invoices, People

app = Eve(validator=ValidatorSQL, data=SQL)

# bind SQLAlchemy
Expand All @@ -14,7 +14,7 @@

# Insert some example data in the db
if not db.session.query(People).count():
from simple import example_data
from eve_sqlalchemy.examples.simple import example_data
for item in example_data.test_data:
db.session.add(People(firstname=item[0], lastname=item[1]))
db.session.add(Invoices(number=42, people_id=1))
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from eve_sqlalchemy.config import DomainConfig, ResourceConfig

from simple.tables import Invoices, People
from eve_sqlalchemy.examples.simple.tables import Invoices, People

DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite://'
Expand Down
File renamed without changes.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
''' Trivial Eve-SQLAlchemy example. '''
from eve import Eve
from eve_sqlalchemy import SQL
from eve_sqlalchemy.config import DomainConfig, ResourceConfig
from eve_sqlalchemy.validation import ValidatorSQL
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import column_property

from eve_sqlalchemy import SQL
from eve_sqlalchemy.config import DomainConfig, ResourceConfig
from eve_sqlalchemy.validation import ValidatorSQL

Base = declarative_base()


Expand Down
21 changes: 17 additions & 4 deletions eve_sqlalchemy/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,22 @@ def parse_dictionary(filter_dict, model):
else:
conditions.append(attr.contains(v))

elif hasattr(attr, 'property') and \
hasattr(attr.property, 'remote_side'): # a relation
for fk in attr.property.remote_side:
conditions.append(sqla_op.eq(fk, v))
# Relations:
elif (hasattr(attr, 'property') and
hasattr(attr.property, 'remote_side')):
relationship = attr.property
if relationship.primaryjoin is not None:
conditions.append(relationship.primaryjoin)
if relationship.secondaryjoin is not None:
conditions.append(relationship.secondaryjoin)
remote_column = list(relationship.remote_side)[0]
if relationship.uselist:
if callable(relationship.argument):
mapper = relationship.argument().__mapper__
else:
mapper = relationship.argument
remote_column = list(mapper.primary_key)[0]
conditions.append(sqla_op.eq(remote_column, v))

else:
try:
Expand All @@ -93,6 +105,7 @@ def parse_dictionary(filter_dict, model):
else:
new_filter = sqla_op.eq(attr, v)
conditions.append(new_filter)

return conditions


Expand Down
33 changes: 33 additions & 0 deletions eve_sqlalchemy/tests/integration/many_to_many.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from eve_sqlalchemy.examples.many_to_many import settings
from eve_sqlalchemy.examples.many_to_many.domain import Base
from eve_sqlalchemy.tests import TestMinimal

SETTINGS = vars(settings)


class TestManyToMany(TestMinimal):

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

def bulk_insert(self):
self.app.data.insert('children', [{'id': k} for k in range(1, 5)])
self.app.data.insert('parents', [
{'id': 1, 'children': [1, 2]},
{'id': 2, 'children': [1, 3]},
{'id': 3, 'children': []}])

def test_get_related_children_with_where(self):
response, status = self.get('children', '?where={"parents": 1}')
self.assert200(status)
children = response['_items']
self.assertEqual([c['id'] for c in children], [1, 2])

def test_get_related_parents_with_where(self):
response, status = self.get('parents', '?where={"children": 1}')
self.assert200(status)
parents = response['_items']
self.assertEqual([p['id'] for p in parents], [1, 2])
33 changes: 33 additions & 0 deletions eve_sqlalchemy/tests/integration/many_to_one.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from eve_sqlalchemy.examples.many_to_one import settings
from eve_sqlalchemy.examples.many_to_one.domain import Base
from eve_sqlalchemy.tests import TestMinimal

SETTINGS = vars(settings)


class TestManyToOne(TestMinimal):

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

def bulk_insert(self):
self.app.data.insert('children', [{'id': k} for k in range(1, 5)])
self.app.data.insert('parents', [
{'id': 1, 'child': 1},
{'id': 2, 'child': 1},
{'id': 3}])

def test_get_related_children_with_where(self):
response, status = self.get('children', '?where={"parents": 1}')
self.assert200(status)
children = response['_items']
self.assertEqual([c['id'] for c in children], [1])

def test_get_related_parents_with_where(self):
response, status = self.get('parents', '?where={"child": 1}')
self.assert200(status)
parents = response['_items']
self.assertEqual([p['id'] for p in parents], [1, 2])
33 changes: 33 additions & 0 deletions eve_sqlalchemy/tests/integration/one_to_many.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from eve_sqlalchemy.examples.one_to_many import settings
from eve_sqlalchemy.examples.one_to_many.domain import Base
from eve_sqlalchemy.tests import TestMinimal

SETTINGS = vars(settings)


class TestOneToMany(TestMinimal):

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

def bulk_insert(self):
self.app.data.insert('children', [{'id': k} for k in range(1, 5)])
self.app.data.insert('parents', [
{'id': 1, 'children': [1, 2]},
{'id': 2, 'children': []},
{'id': 3, 'children': [4]}])

def test_get_related_children_with_where(self):
response, status = self.get('children', '?where={"parent": 1}')
self.assert200(status)
children = response['_items']
self.assertEqual([c['id'] for c in children], [1, 2])

def test_get_related_parents_with_where(self):
response, status = self.get('parents', '?where={"children": 2}')
self.assert200(status)
parents = response['_items']
self.assertEqual([p['id'] for p in parents], [1])
6 changes: 1 addition & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ commands = py.test {posargs}

[testenv:flake8]
deps = flake8
commands = flake8 eve_sqlalchemy examples *.py
commands = flake8 eve_sqlalchemy *.py

[testenv:isort]
deps = isort
commands =
isort --recursive --check-only --diff -p eve_sqlalchemy eve_sqlalchemy
isort --recursive --check-only --diff -o eve_sqlalchemy \
-p foreign_primary_key -p one_to_many -p many_to_many \
-p many_to_one -p simple \
examples

[testenv:rstcheck]
deps = rstcheck
Expand Down

0 comments on commit 916628e

Please sign in to comment.