Skip to content

Commit e97fa9a

Browse files
author
Kareem Zidane
authored
Merge pull request #158 from cs50/postgres/none
v7.0.1
2 parents a88fa09 + 7ed6c52 commit e97fa9a

File tree

6 files changed

+36
-27
lines changed

6 files changed

+36
-27
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,14 @@ jobs:
2626
python-version: '3.6'
2727
- name: Setup databases
2828
run: |
29-
python setup.py install
30-
pip install mysqlclient
31-
pip install psycopg2-binary
32-
touch test.db test1.db
29+
pip install .
30+
pip install mysqlclient psycopg2-binary
3331
- name: Run tests
3432
run: python tests/sql.py
3533
- name: Install pypa/build
36-
run: |
37-
python -m pip install build --user
34+
run: python -m pip install build --user
3835
- name: Build a binary wheel and a source tarball
39-
run: |
40-
python -m build --sdist --wheel --outdir dist/ .
36+
run: python -m build --sdist --wheel --outdir dist/ .
4137
- name: Deploy to PyPI
4238
if: ${{ github.ref == 'refs/heads/main' }}
4339
uses: pypa/gh-action-pypi-publish@release/v1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
*.db
66
*.egg-info/
77
*.pyc
8+
build/
89
dist/
910
test.db

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
package_dir={"": "src"},
1717
packages=["cs50"],
1818
url="https://github.com/cs50/python-cs50",
19-
version="7.0.0"
19+
version="7.0.1"
2020
)

src/cs50/_engine.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import threading
2+
import warnings
23

34
from ._engine_util import create_engine
45

@@ -11,6 +12,7 @@ class Engine:
1112
"""
1213

1314
def __init__(self, url):
15+
url = _replace_scheme_if_postgres(url)
1416
self._engine = create_engine(url)
1517

1618
def get_transaction_connection(self):
@@ -64,3 +66,23 @@ def _thread_local_connections():
6466
connections = thread_local_data.connections = {}
6567

6668
return connections
69+
70+
def _replace_scheme_if_postgres(url):
71+
"""
72+
Replaces the postgres scheme with the postgresql scheme if possible since the postgres scheme
73+
is deprecated.
74+
75+
:returns: url with postgresql scheme if the scheme was postgres; otherwise returns url as is
76+
"""
77+
78+
if url.startswith("postgres://"):
79+
with warnings.catch_warnings():
80+
warnings.simplefilter("always")
81+
warnings.warn(
82+
"The postgres:// scheme is deprecated and will not be supported in the next major"
83+
+ " release of the library. Please use the postgresql:// scheme instead.",
84+
DeprecationWarning
85+
)
86+
url = f"postgresql{url[len('postgres'):]}"
87+
88+
return url

src/cs50/_sql_sanitizer.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ def escape(self, value):
6666
return sqlparse.sql.Token(sqlparse.tokens.String, string_processor(value))
6767

6868
if value is None:
69-
return sqlparse.sql.Token(
70-
sqlparse.tokens.Keyword,
71-
sqlalchemy.types.NullType().literal_processor(self._dialect)(value))
69+
return sqlparse.sql.Token(sqlparse.tokens.Keyword, "NULL")
7270

7371
raise RuntimeError(f"unsupported value: {value}")
7472

tests/sql.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010

1111
class SQLTests(unittest.TestCase):
12-
1312
def test_multiple_statements(self):
1413
self.assertRaises(RuntimeError, self.db.execute, "INSERT INTO cs50(val) VALUES('baz'); INSERT INTO cs50(val) VALUES('qux')")
1514

@@ -133,20 +132,10 @@ def test_identifier_case(self):
133132
self.assertIn("count", self.db.execute("SELECT 1 AS count")[0])
134133

135134
def tearDown(self):
136-
self.db.execute("DROP TABLE cs50")
135+
self.db.execute("DROP TABLE IF EXISTS cs50")
137136
self.db.execute("DROP TABLE IF EXISTS foo")
138137
self.db.execute("DROP TABLE IF EXISTS bar")
139138

140-
@classmethod
141-
def tearDownClass(self):
142-
try:
143-
self.db.execute("DROP TABLE IF EXISTS cs50")
144-
except Warning as e:
145-
# suppress "unknown table"
146-
if not str(e).startswith("(1051"):
147-
raise e
148-
149-
150139
class MySQLTests(SQLTests):
151140
@classmethod
152141
def setUpClass(self):
@@ -156,7 +145,6 @@ def setUp(self):
156145
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER NOT NULL AUTO_INCREMENT, val VARCHAR(16), bin BLOB, PRIMARY KEY (id))")
157146
self.db.execute("DELETE FROM cs50")
158147

159-
160148
class PostgresTests(SQLTests):
161149
@classmethod
162150
def setUpClass(self):
@@ -169,9 +157,11 @@ def setUp(self):
169157
def test_cte(self):
170158
self.assertEqual(self.db.execute("WITH foo AS ( SELECT 1 AS bar ) SELECT bar FROM foo"), [{"bar": 1}])
171159

160+
def test_postgres_scheme(self):
161+
db = SQL("postgres://postgres:[email protected]/test")
162+
db.execute("SELECT 1")
172163

173164
class SQLiteTests(SQLTests):
174-
175165
@classmethod
176166
def setUpClass(self):
177167
open("test.db", "w").close()
@@ -283,7 +273,6 @@ def test_named(self):
283273
self.assertRaises(RuntimeError, self.db.execute, "INSERT INTO foo VALUES (:bar, :baz)", bar='bar', baz='baz', qux='qux')
284274
self.assertRaises(RuntimeError, self.db.execute, "INSERT INTO foo VALUES (:bar, :baz)", 'baz', bar='bar')
285275

286-
287276
def test_numeric(self):
288277
self.db.execute("CREATE TABLE foo (firstname STRING, lastname STRING)")
289278

@@ -319,6 +308,9 @@ def test_numeric(self):
319308
def test_cte(self):
320309
self.assertEqual(self.db.execute("WITH foo AS ( SELECT 1 AS bar ) SELECT bar FROM foo"), [{"bar": 1}])
321310

311+
def test_none(self):
312+
self.db.execute("CREATE TABLE foo (val INTEGER)")
313+
self.db.execute("SELECT * FROM foo WHERE val = ?", None)
322314

323315
if __name__ == "__main__":
324316
suite = unittest.TestSuite([

0 commit comments

Comments
 (0)