GithubHelp home page GithubHelp logo

cs50 / python-cs50 Goto Github PK

View Code? Open in Web Editor NEW
629.0 55.0 253.0 360 KB

This is CS50's library for Python.

Home Page: https://cs50.readthedocs.io/library/python/

License: GNU General Public License v3.0

Python 99.21% HTML 0.48% Dockerfile 0.32%

python-cs50's Introduction

CS50 Library for Python

Installation

pip3 install cs50

Usage

import cs50

...

f = cs50.get_float();
i = cs50.get_int();
s = cs50.get_string();

Testing

  1. In one terminal, execute:

    cd python-cs50
    docker compose build
    docker compose up
    
  2. In another terminal, execute:

    docker exec -it python-cs50 bash -l
    

    And then execute, e.g.:

    python tests/sql.py
    

Sample Tests

import cs50
db = cs50.SQL("sqlite:///foo.db")
db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
db.execute("INSERT INTO cs50 (val) VALUES('a')")
db.execute("INSERT INTO cs50 (val) VALUES('b')")
db.execute("BEGIN")
db.execute("INSERT INTO cs50 (val) VALUES('c')")
db.execute("INSERT INTO cs50 (val) VALUES('x')")
db.execute("INSERT INTO cs50 (val) VALUES('y')")
db.execute("ROLLBACK")
db.execute("INSERT INTO cs50 (val) VALUES('z')")
db.execute("COMMIT")

---

import cs50
db = cs50.SQL("mysql://root@localhost/test")
db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
db.execute("INSERT INTO cs50 (val) VALUES('a')")
db.execute("INSERT INTO cs50 (val) VALUES('b')")
db.execute("BEGIN")
db.execute("INSERT INTO cs50 (val) VALUES('c')")
db.execute("INSERT INTO cs50 (val) VALUES('x')")
db.execute("INSERT INTO cs50 (val) VALUES('y')")
db.execute("ROLLBACK")
db.execute("INSERT INTO cs50 (val) VALUES('z')")
db.execute("COMMIT")

---

import cs50
db = cs50.SQL("postgresql://postgres@localhost/test")
db.execute("CREATE TABLE IF NOT EXISTS cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16), bin BYTEA)")
db.execute("INSERT INTO cs50 (val) VALUES('a')")
db.execute("INSERT INTO cs50 (val) VALUES('b')")
db.execute("BEGIN")
db.execute("INSERT INTO cs50 (val) VALUES('c')")
db.execute("INSERT INTO cs50 (val) VALUES('x')")
db.execute("INSERT INTO cs50 (val) VALUES('y')")
db.execute("ROLLBACK")
db.execute("INSERT INTO cs50 (val) VALUES('z')")
db.execute("COMMIT")

python-cs50's People

Contributors

aivarannamaa avatar cbscribe avatar chrisgzf avatar cmlsharp avatar dmalan avatar glennhart avatar glennholloway avatar jsarchibald avatar kzidane avatar matthiaswenz avatar rongxin-liu avatar up-n-atom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-cs50's Issues

Heroku docs: Postgres URI won't work if not changed to postgresql://

And can't edit the URI on Heroku.

In the docs, step 16 is now:

In CS50 IDE, open application.py in finance/ and replace

db = SQL("sqlite:///finance.db")

with

db = SQL(os.getenv("DATABASE_URL"))

Instead, it could be something like:

In CS50 IDE, open application.py in finance/ and replace

db = SQL("sqlite:///finance.db")

with

uri = os.getenv("DATABASE_URL") 
if uri.startswith("postgres://"):
    uri = uri.replace("postgres://", "postgresql://", 1)
db = SQL(uri)

This fixes the issue.

Error while deploying to Heroku

I cannot delpoy for heroku. I get the following output.

ERROR: Could not find a version that satisfies the requirement apsw==3.28.0.post1 (from -r /tmp/build_d26e4ecc/requirements.txt (line 4)) (from versions: 3.8.2.post1, 3.8.5.post1, 3.8.6.post1, 3.8.7.1.post1, 3.8.7.2.post1, 3.8.7.3.post1, 3.8.8.1.post1, 3.8.8.2.post1, 3.8.9.post1, 3.8.10.1.post1, 3.8.11.1.post1, 3.9.2.post1) remote: ERROR: No matching distribution found for apsw==3.28.0.post1 (from -r /tmp/build_d26e4ecc/requirements.txt (line 4))

Why is this so? How to fix this?

Trying to INSERT None results in CompileError

I'm working on a project where sometimes I have to insert a None value into the database. This would be done in a way like this:

something = None
otherthing = 2
...  # doing some stuff
db.execute("INSERT INTO some_table (col1, col2) VALUES (?, ?)", something, otherthing)

The database schema allows the column to be NULL.

However, this results in an error: sqlalchemy.exc.CompileError: Don't know how to render literal SQL value: None

I tried testing just this insert statement by itself, on a fresh install, just to be sure.

python3 -m venv random
cd random
touch test.db
. bin/activate
pip install cs50
python
>>> import cs50
>>> db = cs50.SQL("sqlite:///test.db")
>>> db.execute("INSERT INTO test VALUES(?)", None)

which resulted in the following traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/random/lib/python3.8/site-packages/cs50/sql.py", line 21, in decorator
    return f(*args, **kwargs)
  File "/tmp/random/lib/python3.8/site-packages/cs50/sql.py", line 178, in execute
    _args = ", ".join([str(self._escape(arg)) for arg in args])
  File "/tmp/random/lib/python3.8/site-packages/cs50/sql.py", line 178, in <listcomp>
    _args = ", ".join([str(self._escape(arg)) for arg in args])
  File "/tmp/random/lib/python3.8/site-packages/cs50/sql.py", line 475, in _escape
    return __escape(value)
  File "/tmp/random/lib/python3.8/site-packages/cs50/sql.py", line 465, in __escape
    sqlalchemy.types.NullType().literal_processor(self._engine.dialect)(value))
  File "/tmp/random/lib/python3.8/site-packages/sqlalchemy/sql/sqltypes.py", line 3169, in process
    raise exc.CompileError(
sqlalchemy.exc.CompileError: Don't know how to render literal SQL value: None

The problem seems to be with line 465 in sql.py (from manual testing and the traceback) with sqlalchemy.types.NullType().literal_processor(self._engine.dialect)(value)

Trying to call sqlalchemy.types.NullType().literal_processor(self._engine.dialect)(None) directly results in the same error.

The problem can be fixed by changing

    return sqlparse.sql.Token(
        sqlparse.tokens.Keyword,
        sqlalchemy.types.NullType().literal_processor(self._engine.dialect)(value))

to

    return sqlparse.sql.Token(
        sqlparse.tokens.Keyword,
        "NULL")

since None is always going to be NULL.

I've gotten the same problem on both Ubuntu 20.04 and Windows 10, using the same setup as I described above. Both were running Python 3.8.5 and cs50 6.0.4.

normalize whitespace in log messages

DEBUG:cs50.sql:SELECT * FROM places
                          WHERE 37.33227322670292 <= latitude AND latitude <= 37.51481551687353 AND (-122.45715756835938 <= longitude AND longitude <= -121.86664243164063)
                          GROUP BY country_code, place_name, admin_code1
                          ORDER BY RANDOM()
                          LIMIT 10

SQL SELECT returns True when it begins with a comment

Not sure if this is expected, but caused some issues for check50...

Let's say we set up a database as:

$ echo "CREATE TABLE users (name TEXT); INSERT INTO users (name) VALUES ('Alice')" | sqlite3 foo.db

And run the following Python program:

from cs50 import SQL
db = SQL("sqlite:///foo.db")
with open("query.sql") as f:
    print(db.execute(f.read()))

If query.sql contains

SELECT * FROM users

the program prints the contents of the table, but if query.sql contains

-- Get all users
SELECT * FROM users

then the return of db.execute is just True.

cc @dmalan @kzidane

decide how to handle INSERT OR IGNORE

SQLite seems to return 0 when using INSERT OR IGNORE and there's an IntegrityError. Perhaps SQL.execute should return None in such cases instead of 0 for clarity.

Unable to INSERT/UPDATE to Postgres SQL Database on Heroku #118

This was an issue that was previous posted here under the #118 and it was closed by the staff with the argument that it was fixed but it hasn't been.

I'm trying to deploy an app on Hedoku using the latest version of CS50 and the bug still there. I'm gonna just copy and paste the original message from #118 cause it's exactly the same problem:

"After completing the CS50 Finance assignment, I attempted to move the application to Heroku. I converted the SQLite3 database over to Postgres. I am able to connect to the Heroku database using:
from CS50 import SQL
db = SQL("Heroku---URI")

SELECT statements do work and does retrieve the requested data. However, INSERT and UPDATE statements did not work for me. I was able to INSERT and UPDATE to the database using my computer's command line, as well as from pgAdmin 4.

Finally, I was able to get my CS50 Finance working by importing the sqlalchemy module instead, and adding .fetchall() to the end of SELECT statements and after INSERT/UPDATE statements I added the db.commit() statement in a line below it to save the changes.

I didn't see any additional notes (such as .commit()) in the documentation on how to get the CS50 module to work with a Postgres database. Sorry in advance if there's something that I missed. CS50 is such a tremendous class by the way, it's absolutely brilliant! ๐Ÿ‘"

test, fix cs50.SQL

Ideal to (re-)test SELECTs, INSERTs (with autoincrementing primary keys), UPDATEs, and DELETEs with:

  • SQLite
  • MySQL
  • PostgreSQL

PostgreSQL, in particular, seems not to support lastrowid (cf. http://stackoverflow.com/a/2189662), so I suspect this condition won't catch INSERTs in the same way:

# if INSERT, return primary key value for a newly inserted row
elif result.lastrowid is not None:
    return result.lastrowid

Ergo the parenthetical comments:

# if SELECT (or INSERT with RETURNING), return result set as list of dict objects
...
# if DELETE or UPDATE (or INSERT without RETURNING), return number of rows matched

Goal, then, is to test whether execute indeed behaves exactly as the comments and return values imply:

# if SELECT (or INSERT with RETURNING), return result set as list of dict objects
if result.returns_rows:
    rows = result.fetchall()
    return [dict(row) for row in rows]

# if INSERT, return primary key value for a newly inserted row
elif result.lastrowid is not None:
    return result.lastrowid

# if DELETE or UPDATE (or INSERT without RETURNING), return number of rows matched
else:
    return result.rowcount

Seems reasonable, though, if user is user PostgreSQL, to expect them to use RETURNING id in order to get back INSERTs' autoincremented IDs, a la http://stackoverflow.com/a/8590931.

CC @glennholloway @brianyu28

Getting AttributeError: 'NoneType' object has no attribute 'WeakInstanceDict' while using SQL class in CS50's python library

AttributeError while using SQL class in CS50's Python library in my LInux System. (System information provided in bottom)

@dmalan sir I was doing favorites.py which you demonstrated in week7 SQL lecture in my offline IDE (vscode). Here it is:

favorites.py

import csv

from cs50 import SQL

open("shows.db", "w").close()
db = SQL("sqlite:///shows.db")

db.execute("CREATE TABLE shows (id INTEGER, title TEXT, PRIMARY KEY(id))")
db.execute("CREATE TABLE genres (show_id INTEGER, genre TEXT, FOREIGN KEY(show_id) REFERENCES shows(id))")

with open("Favorite TV Shows - Form Responses 1.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        title = row["title"].strip().upper()

        id = db.execute("INSERT INTO shows (title) VALUES(?)", title)

        for genre in row["genres"].split(", "):
            db.execute("INSERT INTO genres (show_id, genre) VALUES(?, ?)", id, genre)

And here's the error I'm getting.

(py39) shyam@shyam-linux:~/Projects/CS50X/week7/fav$ python favorites.py 
Exception ignored in: <function SQL.__del__ at 0x7f821ae70f70>
Traceback (most recent call last):
  File "/home/shyam/Projects/virtual_env/py39/lib/python3.9/site-packages/cs50/sql.py", line 96, in __del__
  File "/home/shyam/Projects/virtual_env/py39/lib/python3.9/site-packages/cs50/sql.py", line 101, in _disconnect
  File "/home/shyam/Projects/virtual_env/py39/lib/python3.9/site-packages/sqlalchemy/orm/scoping.py", line 145, in remove
  File "/home/shyam/Projects/virtual_env/py39/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1745, in close
  File "/home/shyam/Projects/virtual_env/py39/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1784, in _close_impl
  File "/home/shyam/Projects/virtual_env/py39/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1798, in expunge_all
AttributeError: 'NoneType' object has no attribute 'WeakInstanceDict'

Despite these errors, after checking the shows.db file I found the TABLES created and the data from csv file was successfully inserted into them.

I am very new to python and Computer Science. CS50X is my first course in the subject.

My system:

  • elementary OS 5.1.7 Hera (Built on Ubuntu 18.04.4 LTS) Linux 5.4.0-73-generic
  • Python version: Python 3.9.5
  • cs50 library version: 6.0.4
  • IDE: Visual Studio Code 1.56.2

Syntax error during import

Hey guys,
first of all: thank you so much for offering the cs50 course! It has really helped me understand how a "computer thinks". :)
I also wanted to thank you for maintaining the cs50 python library.
For my final project -which I decided to code on my own computer- I installed the cs50 library especially for the db execute commands.

However, when I try import it into a python project, I get the following SyntaxError:

Traceback (most recent call last): File "facial_rec.py", line 5, in <module> import cs50 File "/usr/local/lib/python3.5/dist-packages/cs50/__init__.py", line 20, in <module> from .sql import SQL File "/usr/local/lib/python3.5/dist-packages/cs50/sql.py", line 404 return sqlparse.sql.Token(sqlparse.tokens.Other, f"x'{value.hex()}'") # https://dev.mysql.com/doc/refman/8.0/en/hexadecimal-literals.html ^ SyntaxError: invalid syntax

I'm running Ubuntu 16.04 (fully updated) in a VM. For coding I use pycharm with Python 3.5 as the interpreter.
Do you guys have any suggestion on how to tackle the problem?

Cheers and stay healthy!

input uses original stdout

Per https://bugs.python.org/issue28373, input uses original stdout even if sys.stdout is wrapped. When students use input and pass in a prompt, stdout buffering is enabled for this even if they import the cs50 module.

One suggested workaround is to override the fileno method but not sure how reliable that is:

import cs50
input("foo") # doesn't use the overridden write method
import cs50
cs50.get_int("foo") # uses the overridden write method

SQL.execute escapes collation-name in ORDER BY clauses


Unfortunately, sqlparse doesn't give us much contextual information to distinguish literals from identifiers. For instance, SELECT ? FROM ? ORDER BY ? parses as:

$ python3
>>> import sqlparse
>>> statements = sqlparse.parse(sqlparse.format("SELECT ? FROM ? ORDER BY ?"))
>>> for token in statements[0].flatten():
...     print(token.__repr__())
... 
<DML 'SELECT' at 0x7F9D5A99CDE0>
<Whitespace ' ' at 0x7F9D5A99CE50>
<Placeholder '?' at 0x7F9D5A99CEC0>
<Whitespace ' ' at 0x7F9D5A99CF30>
<Keyword 'FROM' at 0x7F9D5A99CAD0>
<Whitespace ' ' at 0x7F9D5A926050>
<Placeholder '?' at 0x7F9D5A9260C0>
<Whitespace ' ' at 0x7F9D5A926130>
<Keyword 'ORDER ...' at 0x7F9D5A9261A0>
<Whitespace ' ' at 0x7F9D5A926210>
<Placeholder '?' at 0x7F9D5A926280>

some exceptions in Flask aren't colorized by our monkey-patching

  1. Copy https://gist.github.com/dmalan/14ed9ec6548df079ea4468f435c7dc6b into a directory.
  2. Run pip3 install -r requirements.txt.
  3. Run flask run.
  4. Visit /foo, and you should see that traceback is highlighted by CS50 library: lines that aren't in site-packages are highlighted in yellow.
  5. Visit /bar, and you should see that traceback isn't highlighted.

The lack of highlighting in the last step appears to be the result of https://github.com/pallets/werkzeug/blob/master/werkzeug/serving.py#L284-L295, whereby the traceback being printed at that point in the app's lifecycle is coming from werkzeug.debug.tbtools.get_current_traceback, specifically traceback.plaintext. Would be ideal to format traceback.plaintext using https://github.com/cs50/python-cs50/blob/develop/src/cs50/cs50.py#L68 as well, though currently our function's signature expects (type, value, tb).

Perhaps simplest to monkey-patch werkzeug.debug.tbtools.get_current_traceback in https://github.com/cs50/python-cs50/blob/develop/src/cs50/flask.py, just as we do flask.logging.default_handler.formatter.formatException? Or monkey-patch the Traceback.plaintext property instead, https://github.com/pallets/werkzeug/blob/master/werkzeug/debug/tbtools.py#L379?

CS50 module prevents ability to import local python files

### Note: This does not happen on CS50 Web IDE.
### Note: I was using VSCode on my PC.
### Note: It is not necessarily an issue, but I think you should definitely point it out in the course.

While working on pset7 from CS50 on edX,

In the application.py, if I imported the CS50 module before I import the functions in helpers.py,
which is located in the same directory as application.py.

application.py:

import cs50
import re
from flask import Flask, abort, redirect, render_template, request
from html import escape
from werkzeug.exceptions import default_exceptions, HTTPException

from helpers import lines, sentences, substrings

Then I get this error:

Traceback (most recent call last):
  File "/home/filip/Web/Workspace/similarities/application.py", line 7, in <module>
    from helpers import lines, sentences, substrings
ModuleNotFoundError: No module named 'helpers'

But if I move the

import cs50

below

from helpers import lines, sentences, substrings

or if I move the

from helpers import lines, sentences, substrings

above the

import cs50

statement,

Modified application.py:

import re
from flask import Flask, abort, redirect, render_template, request
from html import escape
from werkzeug.exceptions import default_exceptions, HTTPException

from helpers import lines, sentences, substrings

import cs50

then everything works fine, because the CS50 module erases the local directory from sys.path from which apllication.py was ran after the local helpers import is done.

sqlite db is locked for all clients

When starting a transaction from > 1 clients, the database file appears to be locked for all clients, rather than all except one.

Steps to reproduce:

In terminal 1:

$ python3
>>> import cs50
>>> db = cs50.SQL('sqlite:///foo.db')
>>> db.execute('begin transaction')
>>> db.execute('update x set y = 1')

In terminal 2:

>>> import cs50
>>> db = cs50.SQL('sqlite:///foo.db')
>>> db.execute('begin transaction')
>>> db.execute('update x set y = 2')

In terminal 1:

>>> db.execute('commit')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/cs50/sql.py", line 21, in decorator
    return f(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/cs50/sql.py", line 388, in execute
    raise e
RuntimeError: database is locked

Same exception is raised in terminal 2.

PIP3 install cs50 no longer works

WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/cs50/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/cs50/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/cs50/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/cs50/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/cs50/
ERROR: Could not find a version that satisfies the requirement cs50 (from versions: none)
ERROR: No matching distribution found for cs50

This is on ubuntu 20 , any solutions?

Allow for multiple database connections in the same request

Issue when a user has two or more databases -- say, test1.db and test2.db -- that they try to use in the same request. The way the library currently works, whichever database I execute on first in this request will be the only database I'm allowed to connect to in the request. So if I try test1.execute(...) followed by test2.execute(...) in the same request, I'm not going to get what I wanted, since the library limits us to one database connection per request -- in this case, the library will try to execute my second SQL statement on test1.db. And that's because of the request global flask.g._connection we're setting, and then using as a gatekeeper against opening new connections.

No pip package for new cs50 library 2016

"pip install cs50" is installing this one >> https://pypi.python.org/pypi/CS50/0.2

Here makefile is working though due to docker or something else

Anyway, My problem is resolved by copying all .py src files to my locally installed python3.6
mkdir ~/.myPython/lib/python3.6/site-packages/cs50
cp src/* ~/.myPython/lib/python3.6/site-packages/cs50/
[ /usr/lib/python3/dist-packages/cs50 for situation It varies ]

But one dependency is needed for sql.py that SQLALchemy
pip install SQLAlchemy

Missing "install" make rule

Trying to follow instructions to install lib50-python on macOS Sierra (per the README) I encountered the following error:

$ make install
make: *** No rule to make target `install'.  Stop.

I cannot see an easy way to implement this myself (it does not seem easy to get the user's $PYTHONPATH. And even if we got it and we could move the file to that directory, would it be too much code to put on a Makefile?)

Is there any chance this module could be made available through pip install cs50? Or maybe it is better to provide some instructions on how access the module by placing cs50.py on the same directory as the main file?

SQLite objects created in a thread can only be used in that same thread

I've been working on my final project for a few weeks now and everything was working well until I had to rebuild my virtual environment recently. I'm now getting an intermittent error when running SQL queries via db.execute()

sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 4618292736 and this is thread id 123145406357504.

DEBUG: SELECT id, hash, profile_complete FROM users WHERE username = 'tom@tom'
INFO: 127.0.0.1 - - [14/Dec/2020 19:54:55] "POST /login HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1204, in _execute_context
context = constructor(dialect, self, conn, *args)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 806, in _init_compiled
self.cursor = self.create_cursor()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 1162, in create_cursor
return self._dbapi_connection.cursor()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 1000, in cursor
return self.connection.cursor(*args, **kwargs)
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 4618292736 and this is thread id 123145406357504.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 749, in _rollback_impl
self.engine.dialect.do_rollback(self.connection)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 543, in do_rollback
dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 4618292736 and this is thread id 123145406357504.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/cs50/sql.py", line 324, in execute
connection.execute(sqlalchemy.text("BEGIN"))
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1011, in execute
return meth(self, multiparams, params)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/sql/elements.py", line 298, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1124, in _execute_clauseelement
ret = self._execute_context(
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1206, in _execute_context
self._handle_dbapi_exception(
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1505, in handle_dbapi_exception
self.autorollback()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 82, in exit
compat.raise
(value, with_traceback=traceback)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise

raise exception
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1505, in _handle_dbapi_exception
self._autorollback()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 888, in _autorollback
self._root._rollback_impl()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 751, in _rollback_impl
self.handle_dbapi_exception(e, None, None, None, None)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1405, in handle_dbapi_exception
util.raise
(
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise

raise exception
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 749, in _rollback_impl
self.engine.dialect.do_rollback(self.connection)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 543, in do_rollback
dbapi_connection.rollback()
sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 4618292736 and this is thread id 123145406357504.
(Background on this error at: http://sqlalche.me/e/13/f405)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 2464, in call
return self.wsgi_app(environ, start_response)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functionsrule.endpoint
File "/Users/tomburgess/onedrive/projects/cs50/final/squawk7000/app.py", line 133, in login
rows = db.execute("SELECT id, hash, profile_complete FROM users WHERE username = :username",
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/cs50/sql.py", line 21, in decorator
return f(*args, **kwargs)
File "/Users/tomburgess/environments/cs50/lib/python3.8/site-packages/cs50/sql.py", line 384, in execute
raise e
RuntimeError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 4618292736 and this is thread id 123145406357504.

Expose a SQL.escape() function?

To solve, e.g.:

likes = []
for keyword in keywords:
    likes.append("name LIKE " + str(db._escape("%" + keyword +"%")))
ors = " OR ".join(likes)

catalog = db.execute(f"SELECT * FROM catalog WHERE overall_eval >= ? AND workload_eval <= ? AND ({ors})", rating, workload)

deprecation warning about werkzeug in new IDE

in new IDE, some users getting a deprecation warning about werkzeug


ERROR:werkzeug:Error on request:

Traceback (most recent call last):

File "/opt/pyenv/versions/3.7.2/lib/python3.7/site-packages/werkzeug/serving.py", line 302, in run_wsgi

execute(self.server.app)

File "/opt/pyenv/versions/3.7.2/lib/python3.7/site-packages/werkzeug/serving.py", line 290, in execute

application_iter = app(environ, start_response)

File "/home/ubuntu/environment/project/application.py", line 24, in <module>

app = Flask(__name__)

File "/opt/pyenv/versions/3.7.2/lib/python3.7/site-packages/cs50/flask.py", line 32, in after

self.wsgi_app = ProxyFix(self.wsgi_app)

File "/opt/pyenv/versions/3.7.2/lib/python3.7/site-packages/werkzeug/contrib/fixers.py", line 141, in __init__

stacklevel=2,

DeprecationWarning: 'werkzeug.contrib.fixers.ProxyFix' has moved to 'werkzeug.middleware.proxy_fix.ProxyFix'. This import is deprecated as of version 0.15 and will be removed in 1.0.```

add support for BLOB, etc.?

I'm not sure how to pass them at the moment, since we're reducing the whole statement to a str ourselves. And a query like

db.execute("SELECT * FROM Employee WHERE FirstName = ?", b'\x00')

currently errs with

ValueError: the query contains a null character

at this line of ours:

result = self.engine.execute(statement)

@kzidane, know how/if we can represent binary data in strings in a cross-DBMS way? Or do we need to revert to binding parameters for those?

Unable to INSERT/UPDATE to Postgres Database on Heroku

After completing the CS50 Finance assignment, I attempted to move the application to Heroku. I converted the SQLite3 database over to Postgres. I am able to connect to the Heroku database using:
from CS50 import SQL
db = SQL("Heroku---URI")

SELECT statements do work and does retrieve the requested data. However, INSERT and UPDATE statements did not work for me. I was able to INSERT and UPDATE to the database using my computer's command line, as well as from pgAdmin 4.

Finally, I was able to get my CS50 Finance working by importing the sqlalchemy module instead, and adding .fetchall() to the end of SELECT statements and after INSERT/UPDATE statements I added the db.commit() statement in a line below it to save the changes.

I didn't see any additional notes (such as .commit()) in the documentation on how to get the CS50 module to work with a Postgres database. Sorry in advance if there's something that I missed. CS50 is such a tremendous class by the way, it's absolutely brilliant! ๐Ÿ‘

Improve error reporting

Currently, a syntax error (e.g., a missing paren) might yield this output from SQL.execute, with the DEBUG line in red:

DEBUG:cs50:INSERT INTO tbl (id, foo VALUES(1, NULL)
Traceback (most recent call last):
  File "foo.py", line 8, in <module>
    print(db.execute("INSERT INTO tbl (id, foo VALUES(1, NULL)"))
  File "/mnt/src/cs50/sql.py", line 289, in execute
    raise e
RuntimeError: (sqlite3.OperationalError) near "VALUES": syntax error
[SQL: INSERT INTO tbl (id, foo VALUES(1, NULL)]
(Background on this error at: http://sqlalche.me/e/e3q8)

Could be simplified to:

DEBUG:cs50:INSERT INTO tbl (id, foo VALUES(1, NULL)
Traceback (most recent call last):
  File "foo.py", line 8, in <module>
    print(db.execute("INSERT INTO tbl (id, foo VALUES(1, NULL)"))
  File "/mnt/src/cs50/sql.py", line 289, in execute
    raise e
RuntimeError: near "VALUES": syntax error

Meanwhile, an IntegrityError yields the below, with the DEBUG line in yellow, but doesn't report the actual issue:

DEBUG:cs50:INSERT INTO tbl (id, foo) VALUES(1, NULL)

This could be enhanced as follows, with the first DEBUG line in yellow, the second in white (since it's not a query):

DEBUG:cs50:INSERT INTO tbl (id, foo) VALUES(1, NULL)
DEBUG:cs50:NOT NULL constraint failed: tbl.foo

db.execute() returning KeyError when using one keyword argument twice

below is the example of SQL query which produces KeyError:
db.execute("SELECT col1,col2 FROM table WHERE col3=:email AND col4=:email AND col5=:dob", email=email, dob=dob)

Here, the same keyword argument :email is used twice in the query but it raises KeyError in cs50 7.0.1 but it was working fine previously.

Using '?' positional arguments works fine.

OutputAfterSQL_Query

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.