__all__ = ["Serializer", "Deserializer", "dumps", "loads"]
-def Serializer(*args, **kw):
- pickler = pickle.Pickler(*args, **kw)
+class Serializer(pickle.Pickler):
- def persistent_id(obj):
+ def persistent_id(self, obj):
# print "serializing:", repr(obj)
if isinstance(obj, Mapper) and not obj.non_primary:
id_ = "mapper:" + b64encode(pickle.dumps(obj.class_))
return None
return id_
- pickler.persistent_id = persistent_id
- return pickler
-
our_ids = re.compile(
r"(mapperprop|mapper|mapper_selectable|table|column|"
)
-def Deserializer(file, metadata=None, scoped_session=None, engine=None):
- unpickler = pickle.Unpickler(file)
+class Deserializer(pickle.Unpickler):
+
+ def __init__(self, file, metadata=None, scoped_session=None, engine=None):
+ super().__init__(file)
+ self.metadata = metadata
+ self.scoped_session = scoped_session
+ self.engine = engine
- def get_engine():
- if engine:
- return engine
- elif scoped_session and scoped_session().bind:
- return scoped_session().bind
- elif metadata and metadata.bind:
- return metadata.bind
+ def get_engine(self):
+ if self.engine:
+ return self.engine
+ elif self.scoped_session and self.scoped_session().bind:
+ return self.scoped_session().bind
else:
return None
- def persistent_load(id_):
+ def persistent_load(self, id_):
m = our_ids.match(str(id_))
if not m:
return None
cls = pickle.loads(b64decode(mapper))
return class_mapper(cls).attrs[keyname]
elif type_ == "table":
- return metadata.tables[args]
+ return self.metadata.tables[args]
elif type_ == "column":
table, colname = args.split(":")
- return metadata.tables[table].c[colname]
+ return self.metadata.tables[table].c[colname]
elif type_ == "session":
- return scoped_session()
+ return self.scoped_session()
elif type_ == "engine":
- return get_engine()
+ return self.get_engine()
else:
raise Exception("Unknown token: %s" % type_)
- unpickler.persistent_load = persistent_load
- return unpickler
-
def dumps(obj, protocol=pickle.HIGHEST_PROTOCOL):
buf = BytesIO()
postgresql = ["psycopg2>=2.7"]
postgresql-pg8000 = ["pg8000>=1.29.3"]
postgresql-asyncpg = [
- "sqlalchemy[asyncio]",
+ "greenlet!=0.4.17", # same as ".[asyncio]" if this syntax were supported
"asyncpg",
]
postgresql-psycopg2binary = ["psycopg2-binary"]
postgresql-psycopgbinary = ["psycopg[binary]>=3.0.7,!=3.1.15"]
pymysql = ["pymysql"]
aiomysql = [
- "sqlalchemy[asyncio]",
+ "greenlet!=0.4.17", # same as ".[asyncio]" if this syntax were supported
"aiomysql",
]
aioodbc = [
- "sqlalchemy[asyncio]",
+ "greenlet!=0.4.17", # same as ".[asyncio]" if this syntax were supported
"aioodbc",
]
asyncmy = [
- "sqlalchemy[asyncio]",
+ "greenlet!=0.4.17", # same as ".[asyncio]" if this syntax were supported
"asyncmy>=0.2.3,!=0.2.4,!=0.2.6",
]
aiosqlite = [
- "sqlalchemy[asyncio]",
+ "greenlet!=0.4.17", # same as ".[asyncio]" if this syntax were supported
"aiosqlite",
]
sqlcipher = ["sqlcipher3_binary"]
[tox]
envlist = py
+[greenletextras]
+extras=
+ asyncio
+ sqlite: aiosqlite
+ sqlite_file: aiosqlite
+ postgresql: postgresql_asyncpg
+ mysql: asyncmy
+ mysql: aiomysql
+ mssql: aioodbc
+
+ # not greenlet, but tends to not have packaging until the py version
+ # has been fully released
+ mssql: mssql_pymssql
+
[testenv]
cov_args=--cov=sqlalchemy --cov-report term --cov-append --cov-report xml --exclude-tag memory-intensive --exclude-tag timing-intensive -k "not aaa_profiling"
cov: True
extras=
- asyncio
- sqlite: aiosqlite
- sqlite_file: aiosqlite
- sqlite_file: sqlcipher; python_version < '3.10'
+ py{3,38,39,310,311,312}: {[greenletextras]extras}
+
+ py{38,39,310}-sqlite_file: sqlcipher
postgresql: postgresql
- postgresql: postgresql_asyncpg
postgresql: postgresql_pg8000
postgresql: postgresql_psycopg
mysql: mysql
mysql: pymysql
- mysql: asyncmy
- mysql: aiomysql
mysql: mariadb_connector
oracle: oracle
oracle: oracle_oracledb
mssql: mssql
- mssql: aioodbc
- py{3,37,38,39,310,311}-mssql: mssql_pymssql
install_command=
# TODO: I can find no way to get pip / tox / anyone to have this
# tracked by https://github.com/pytest-dev/pytest-xdist/issues/907
pytest-xdist!=3.3.0
- py312: greenlet>=3.0.0a1
-
dbapimain-sqlite: git+https://github.com/omnilib/aiosqlite.git\#egg=aiosqlite
dbapimain-sqlite: git+https://github.com/coleifer/sqlcipher3.git\#egg=sqlcipher3
dbapimain-oracle: git+https://github.com/oracle/python-cx_Oracle.git\#egg=cx_Oracle
- py312-mssql: git+https://github.com/mkleehammer/pyodbc.git\#egg=pyodbc
+ py313-mssql: git+https://github.com/mkleehammer/pyodbc.git\#egg=pyodbc
dbapimain-mssql: git+https://github.com/mkleehammer/pyodbc.git\#egg=pyodbc
cov: pytest-cov
WORKERS={env:TOX_WORKERS:-n4 --max-worker-restart=5}
-
-
nocext: DISABLE_SQLALCHEMY_CEXT=1
cext: REQUIRE_SQLALCHEMY_CEXT=1
cov: COVERAGE={[testenv]cov_args}
oracle: WORKERS={env:TOX_WORKERS:-n2 --max-worker-restart=5}
oracle: ORACLE={env:TOX_ORACLE:--db oracle}
+
oracle: EXTRA_ORACLE_DRIVERS={env:EXTRA_ORACLE_DRIVERS:--dbdriver cx_oracle --dbdriver oracledb --dbdriver oracledb_async}
+ py{313,314}-oracle: EXTRA_ORACLE_DRIVERS={env:EXTRA_ORACLE_DRIVERS:--dbdriver cx_oracle --dbdriver oracledb}
sqlite: SQLITE={env:TOX_SQLITE:--db sqlite}
sqlite_file: SQLITE={env:TOX_SQLITE_FILE:--db sqlite_file}
sqlite: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver pysqlite_numeric --dbdriver aiosqlite}
+ py{313,314}-sqlite: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver pysqlite_numeric}
+
sqlite-nogreenlet: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver pysqlite_numeric}
py{37,38,39}-sqlite_file: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver aiosqlite --dbdriver pysqlcipher}
mysql-nogreenlet: EXTRA_MYSQL_DRIVERS={env:EXTRA_MYSQL_DRIVERS:--dbdriver mysqldb --dbdriver pymysql --dbdriver mariadbconnector}
mssql: MSSQL={env:TOX_MSSQL:--db mssql}
- py{3,38,39,310,311}-mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc --dbdriver pymssql}
- py{3,38,39,310,311}-mssql-nogreenlet: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver pymssql}
- py312-mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc}
- py312-mssql-nogreenlet: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc}
+
+ mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc --dbdriver pymssql}
+ py{313,314}-mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc}
+
+ mssql-nogreenlet: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver pymssql}
+ py{313,314}-mssql-nogreenlet: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc}
oracle,mssql,sqlite_file: IDENTS=--write-idents db_idents.txt
# suddently appearing for it to be stable enough for CI
# pyright
+extras =
+ {[greenletextras]extras}
+
[testenv:mypy]
deps=
pytest>=7.0.0rc1,<8
mypy >= 1.7.0
patch==1.*
types-greenlet
+extras=
+ {[greenletextras]extras}
+
commands =
pytest {env:PYTEST_COLOR} -m mypy {posargs}
{[testenv:mypy]deps}
pytest-cov
+extras=
+ {[greenletextras]extras}
+
commands =
pytest {env:PYTEST_COLOR} -m mypy {env:COVERAGE} {posargs}
# thanks to https://julien.danjou.info/the-best-flake8-extensions/
[testenv:lint]
basepython = python3
+
+extras=
+ {[greenletextras]extras}
+
deps=
flake8==6.1.0
flake8-import-order
deps = {[testenv:lint]deps}
allowlist_externals = {[testenv:lint]allowlist_externals}
commands = {[testenv:lint]commands}
+extras = {[testenv:lint]extras}
+
# command run in the github action when cext are active.
[testenv:github-cext]
+extras=
+ {[greenletextras]extras}
+
deps = {[testenv]deps}
.[aiosqlite]
commands=
# command run in the github action when cext are not active.
[testenv:github-nocext]
+extras=
+ {[greenletextras]extras}
+
deps = {[testenv]deps}
.[aiosqlite]
commands=