tests pass with sqlalchemy 2.0
This commit is contained in:
parent
4c0b082f2b
commit
5ec97e7cd0
|
|
@ -1 +1,2 @@
|
||||||
from kosokoso import *
|
# from kosokoso import *
|
||||||
|
from kosokoso import init_base
|
||||||
|
|
|
||||||
34
kosokoso.py
34
kosokoso.py
|
|
@ -1,6 +1,7 @@
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.orm import declared_attr
|
||||||
from sqlalchemy.ext.associationproxy import association_proxy
|
from sqlalchemy.ext.associationproxy import association_proxy
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -71,16 +72,19 @@ class TagBase(object):
|
||||||
:param tablename: String with name of table.
|
:param tablename: String with name of table.
|
||||||
:return: Class reference or None.
|
:return: Class reference or None.
|
||||||
"""
|
"""
|
||||||
for c in Base._decl_class_registry.values():
|
for c in Base.registry._class_registry.values():
|
||||||
if (hasattr(c, '__tablename__')
|
if getattr(c, '__tablename__', None) == tablename:
|
||||||
and c.__tablename__ == tablename):
|
|
||||||
return c
|
return c
|
||||||
|
# for c in Base._decl_class_registry.values():
|
||||||
|
# if (hasattr(c, '__tablename__')
|
||||||
|
# and c.__tablename__ == tablename):
|
||||||
|
# return c
|
||||||
|
|
||||||
|
|
||||||
db_id = sa.Column(sa.Integer, primary_key=True)
|
db_id = sa.Column(sa.Integer, primary_key=True)
|
||||||
text = sa.Column(sa.Unicode(255, convert_unicode=False),
|
# text = sa.Column(sa.Unicode(255, convert_unicode=False),
|
||||||
unique=True)
|
# unique=True)
|
||||||
# this & collection should be read-only?
|
text = sa.Column(sa.Unicode(255), unique=True)
|
||||||
collection = sa.orm.relationship("TagAssociation",
|
collection = sa.orm.relationship("TagAssociation",
|
||||||
collection_class=TaggedObjectCollection,
|
collection_class=TaggedObjectCollection,
|
||||||
enable_typechecks=True,
|
enable_typechecks=True,
|
||||||
|
|
@ -110,22 +114,17 @@ class TagAssociationBase(object):
|
||||||
__tablename__ = "kk_tag_associations"
|
__tablename__ = "kk_tag_associations"
|
||||||
db_id = sa.Column(sa.Integer, primary_key=True)
|
db_id = sa.Column(sa.Integer, primary_key=True)
|
||||||
tag_id = sa.Column(sa.Integer, sa.ForeignKey("kk_tags.db_id"))
|
tag_id = sa.Column(sa.Integer, sa.ForeignKey("kk_tags.db_id"))
|
||||||
target_table = sa.Column(sa.Unicode(255, convert_unicode=False))
|
# target_table = sa.Column(sa.Unicode(255, convert_unicode=False))
|
||||||
|
target_table = sa.Column(sa.Unicode(255))
|
||||||
target_id = sa.Column(sa.Integer)
|
target_id = sa.Column(sa.Integer)
|
||||||
__mapper_args__ = {
|
__mapper_args__ = {
|
||||||
"polymorphic_on": "target_table"
|
"polymorphic_on": "target_table"
|
||||||
}
|
}
|
||||||
|
|
||||||
# m = sa.orm.mapper(Tag, Tag.__table__, non_primary=True,
|
|
||||||
# primary_key=[Tag.text])
|
|
||||||
# tag_obj = sa.orm.relationship(m)
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def tag_obj(self):
|
def tag_obj(self):
|
||||||
return sa.orm.relationship(Tag)
|
return sa.orm.relationship(Tag)
|
||||||
# tag_obj = sa.orm.relationship(Tag)
|
|
||||||
|
|
||||||
# FIXME doesn't work, may not be needed.
|
|
||||||
# tag_obj = sa.orm.relationship("Tag", back_populates="collection")
|
|
||||||
tag = association_proxy("tag_obj", "text")
|
tag = association_proxy("tag_obj", "text")
|
||||||
|
|
||||||
tracked_obj = None
|
tracked_obj = None
|
||||||
|
|
@ -220,10 +219,11 @@ def init_base(new_base):
|
||||||
def delete_before_insert(mapper, conn, target):
|
def delete_before_insert(mapper, conn, target):
|
||||||
# TODO figure out where exactly transactions happen.
|
# TODO figure out where exactly transactions happen.
|
||||||
# TODO can we just upsert? Or, for that matter, skip the insert?
|
# TODO can we just upsert? Or, for that matter, skip the insert?
|
||||||
r = conn.execute("SELECT db_id FROM kk_tags WHERE text='%s'" %
|
r = conn.execute(text("SELECT db_id FROM kk_tags WHERE text='%s'" %
|
||||||
target.text)
|
target.text))
|
||||||
if r:
|
if r:
|
||||||
conn.execute("DELETE FROM kk_tags WHERE text='%s'" % target.text)
|
conn.execute(text("DELETE FROM kk_tags WHERE text='%s'" %
|
||||||
|
target.text))
|
||||||
|
|
||||||
# i'm not sure if this is necessary -- its purpose is to set the id on
|
# i'm not sure if this is necessary -- its purpose is to set the id on
|
||||||
# our new instance to ensure it matches the old instance. if this
|
# our new instance to ensure it matches the old instance. if this
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,18 @@ import mock
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pprint
|
import pprint
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
import sqlalchemy.orm as orm
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
|
# from . import kosokoso as kk
|
||||||
import libkosokoso as kk
|
import libkosokoso as kk
|
||||||
|
|
||||||
DummyBase = sa.ext.declarative.declarative_base()
|
# DummyBase = sa.orm.declarative_base()
|
||||||
|
DummyBase = orm.declarative_base()
|
||||||
kk.__dict__.update(kk.init_base(DummyBase))
|
kk.__dict__.update(kk.init_base(DummyBase))
|
||||||
|
|
||||||
# TODO make it so DummyBase doesn't have to come after the mixin.
|
# TODO make it so DummyBase doesn't have to come after the mixin.
|
||||||
|
|
@ -83,7 +88,7 @@ class ks_basic(unittest.TestCase):
|
||||||
|
|
||||||
self.session.add(t1)
|
self.session.add(t1)
|
||||||
self.session.add(t2)
|
self.session.add(t2)
|
||||||
self.session.commit()
|
# self.session.commit()
|
||||||
|
|
||||||
# del t1, t2
|
# del t1, t2
|
||||||
ts = self.session.query(kk.Tag).all()
|
ts = self.session.query(kk.Tag).all()
|
||||||
|
|
@ -286,6 +291,7 @@ class ks_basic(unittest.TestCase):
|
||||||
a.tags.extend(l2)
|
a.tags.extend(l2)
|
||||||
self.assertEqual(l, a.tags)
|
self.assertEqual(l, a.tags)
|
||||||
|
|
||||||
|
# @unittest.skip
|
||||||
def test_pretty(self):
|
def test_pretty(self):
|
||||||
"""verify that the example in the readme works."""
|
"""verify that the example in the readme works."""
|
||||||
a = Foo()
|
a = Foo()
|
||||||
|
|
@ -311,12 +317,13 @@ class ks_basic(unittest.TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
actual = []
|
actual = []
|
||||||
actual.append(str(pd.read_sql_query("SELECT * FROM foos",
|
with self.engine.begin() as conn:
|
||||||
self.engine)))
|
actual.append(str(pd.read_sql_query(text("SELECT * FROM foos"),
|
||||||
actual.append(str(pd.read_sql_query("SELECT * FROM kk_tag_associations",
|
conn)))
|
||||||
self.engine)))
|
actual.append(str(pd.read_sql_query(
|
||||||
actual.append(str(pd.read_sql_query("SELECT * FROM kk_tags",
|
text("SELECT * FROM kk_tag_associations"), conn)))
|
||||||
self.engine)))
|
actual.append(str(pd.read_sql_query(text("SELECT * FROM kk_tags"),
|
||||||
|
conn)))
|
||||||
for i in a.tags:
|
for i in a.tags:
|
||||||
actual.append(i)
|
actual.append(i)
|
||||||
actual = '\n'.join(actual)
|
actual = '\n'.join(actual)
|
||||||
|
|
@ -376,5 +383,13 @@ class kk_mocktest(unittest.TestCase):
|
||||||
|
|
||||||
@mock.patch('libkosokoso.Tag', autospec=True)
|
@mock.patch('libkosokoso.Tag', autospec=True)
|
||||||
def test_tag_mock(self, tag_mock):
|
def test_tag_mock(self, tag_mock):
|
||||||
t1 = kk.Tag()
|
t1 = kk.Tag('test')
|
||||||
self.assertIsInstance(t1, mock.NonCallableMagicMock)
|
self.assertIsInstance(t1, mock.NonCallableMagicMock)
|
||||||
|
|
||||||
|
f1 = Foo()
|
||||||
|
f1.tags.append(t1)
|
||||||
|
self.assertIsInstance(f1.kk_tag_associations[0].tag_obj,
|
||||||
|
mock.NonCallableMagicMock)
|
||||||
|
|
||||||
|
# FIXME bypasses mock
|
||||||
|
f1.tags.append('test2')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue