Flask not storing data to database - sql

Database not storing flask data models. Even though the database gets created.
Using postrges, the tables get created in bash view but not in pgAdmin. I have a simple app that needs to store data. Would appreciate help.'
Code uses SQLAlchemy. DO i need to use different library. I am using psycopg2 and sessions but havent imported sessions.
#!flask/bin/python
#!flask/bin/python
from os import linesep
from typing import Mapping, Type from flask
import Flask, jsonify
from flask import request
from slotscal import results
from flask_sqlalchemy
import SQLAlchemy
import time
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']= 'postgresql+psycopg2://postgres:test123#localhost:5432/hqw' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db=SQLAlchemy(app)
db.metadata.clear()
#add parenrts
class Contracts(db.Model):
name=db.Column(db.String(100))
address=db.Column(db.String(42), unique=True, primary_key=True)
fileName=db.Column(db.Integer)
Functions= db.relationship('Function')
Variables= db.relationship('Variable')
StateVariables=db.relationship('StateVariable')
def __init__(self,address,fileName,id,StateVariables,name):
self.address=address
self.fileName=fileName
self.id=id
self.StateVariables=StateVariables
self.name=name
class Function(db.Model):
id=db.Column(db.String(42), db.ForeignKey('contracts.address'), primary_key=True)
name=db.Column(db.String)
lines=db.Column(db.Integer)
ReachingTime=db.Column(db.DateTime)
TrackingTime=db.Column(db.DateTime)
Arguments= db.relationship('Arguments')
def __init__(self,address,ReachingTime,id,TrackingTime,name,lines):
self.address=address
self.ReachingTime=ReachingTime
self.TrackingTime=TrackingTime
self.id=id
self.lines=lines
self.name=name
class Argument(db.Model):
id=db.Column(db.String(42), db.ForeignKey('function.id'), primary_key=True)
Type=db.Column(db.String)
Value=db.Column(db.String)
Name=db.Column(db.String)
def __init__(self,Name, id,Type,Value):
self.Name=Name
self.id=id
self.Type=Type
self.Value=Value
class Variable(db.Model):
VariableName=db.Column(db.String)
id=db.Column(db.String(42),db.ForeignKey('contracts.address'),primary_key=True)
Type=db.Column(db.String)
Value=db.Column(db.String)
StateVaruiable=db.Column(db.Boolean)
Mapping=db.Column(db.Boolean)
def __init__(self,address,Value,Type,id,StateVariables,name):
self.address=address
self.Type=Type
self.Value=Value
self.id=id
self.StateVariables=StateVariables
self.name=name
class m(db.Model):
id=db.Column(db.String(42),db.ForeignKey('variable.id'), primary_key=True)
Type=db.Column(db.String)
Source=db.Column(db.String)
def __init__(self,Type,Source,id):
self.Type=Type
self.id=id
self.Source=Source
class StateVariable(db.Model):
id=StateVariableType=db.Column(db.String)
StateVariableValue=db.Column(db.String)
id=db.Column(db.String(42),db.ForeignKey('contracts.address'),primary_key=True)
def __init__(self,id,StateVariableType,StateVariableValue):
self.StateVariableType=StateVariableType
self.StateVariableValue=StateVariableValue
self.id=id
class Key(db.Model):
id=db.Column(db.String(42),db.ForeignKey('m.id'), primary_key=True)
Value=db.Column(db.String)
Type=db.Column(db.String)
def __init__(self,Value,id,Type):
self.id=id
self.Value=Value
self.Type=Type
class Analysis(db.Model):
id=db.Column(db.String(42),db.ForeignKey('contracts.address'),primary_key=True)
FullTime=db.Column(db.DateTime)
StateVariables=db.Column(db.Integer)
def __init__(self,id,FullTime):
self.id=id
self.FullTime=FullTime
#app.route('/') def index():
return "Hello, World!" #app.route('/process', methods=['POST']) def process():
#print ('h')
header=request.json
#print ('g')
code=header['code']
f=open('code.sol','w')
f.write(code)
f.close()
path='./code.sol' #filename
subcon=header['name'] #name
add=header['address'] #address
contract=Contracts(subcon,add,path)
db.session.add(contract)
db.session.commit()
lst=results(path,subcon,add)
return jsonify({'task': lst})
if __name__ == '__main__':
app.run(debug=True)**

I'm not certain what you use the db.metadata.clear() for in your context.
Most likely, you don't see data in your DB, because there's nothing in your code to create the database relations. Standard solutions would include Alembic (Flask-Migrate package) or adding
with app.app_context():
db.create_all()
to your code.
The particulars are really up to you. Flask-Migrate is quite easy:
Install: pip install flask-migrate
Add to model:
from flask-migrate import Migrate
...
app = Flask(...)
...
#db init code
...
migrate = Migrate(app, db)
Run:
initialize: flask db init
migrate: flask db migrate -m "[YOUR MESSAGE]"
upgrade: flask db upgrade
Here's a good source in addition to the official docs: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iv-database

Related

django rest framework test code self.client.delete problem

from rest_framework import status, response
from rest_framework.test import APITestCase
from lots.models import Lot
class LotsTestCase(APITestCase):
def setUp(self) -> None:
self.lot = Lot.objects.create(name="1",
address="Dont Know",
phone_num="010-4451-2211",
latitude=127.12,
longitude=352.123,
basic_rate=20000,
additional_rate=2000,
partnership=False,
section_count=3,)
def test_delete(self):
response = self.client.delete(f'api/lots/{self.lot["name"]}')
# response = self.client.delete(f'/api/users/{self.users[0].pk}')
# url = reverse(f'/api/lots/{self.lot}', kwargs={'pk': self.lot.pk})
# self.client.delete(url)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(self.lot.objects.filter(pk=self.lot.pk.count()))
I have problems with the test code above. Why doesn't it work? I know it has to do with calling dictionary values but I just can't figure it out. Thanks for your help.
Lot.objects.create(...) returns a Lot type so you access name by self.lot.name.

How to use `from_orm` if the pydantic model defines aliases?

Though the pydantic's ORM mode is documented here, unfortunately there is no documentation for usage with aliases.
How to use from_orm if the pydantic model defines aliases?
It seems that the from_orm factory forgets about all non-aliased names if aliases exist. - See error message and the corresponding code below. Is that a bug or a feature?
The code snippet below fails unexpectedly with a validation error:
pydantic.error_wrappers.ValidationError: 1 validation error for SimpleModel
threeWordsId
field required (type=value_error.missing)
from sqlalchemy import Column, String
from sqlalchemy.ext.declarative import declarative_base
from pydantic import BaseModel, Field
Base = declarative_base()
class SimpleOrm(Base):
__tablename__ = 'simples'
three_words_id = Column(String, primary_key=True)
class SimpleModel(BaseModel):
three_words_id: str = Field(..., alias="threeWordsId")
class Config:
orm_mode=True
simple_orm = SimpleOrm(three_words_id='abc')
simple_oops = SimpleModel.from_orm(simple_orm)
Use allow_population_by_field_name = True in config.
Like
from sqlalchemy import Column, String
from sqlalchemy.ext.declarative import declarative_base
from pydantic import BaseModel, Field
Base = declarative_base()
class SimpleOrm(Base):
__tablename__ = 'simples'
three_words_id = Column(String, primary_key=True)
class SimpleModel(BaseModel):
three_words_id: str = Field(..., alias="threeWordsId")
class Config:
orm_mode = True
allow_population_by_field_name = True
# allow_population_by_alias = True # in case pydantic.version.VERSION < 1.0
simple_orm = SimpleOrm(three_words_id='abc')
simple_oops = SimpleModel.from_orm(simple_orm)
print(simple_oops.json()) # {"three_words_id": "abc"}
print(simple_oops.json(by_alias=True)) # {"threeWordsId": "abc"}
from fastapi import FastAPI
app = FastAPI()
#app.get("/model", response_model=SimpleModel)
def get_model():
# results in {"threeWordsId":"abc"}
return SimpleOrm(three_words_id='abc')

tornado's AsyncHttpTestCase is not available outside self.fetch

I have an AsyncHttpTestCase and I want to access it from methods besides self.fetch. Specifically, I have a SockJS handler that I want a sockjs-client to attach too for my tests.
I've discovered that even though self.get_url('/foo') returns a valid url, that url does not respond to anything except for self.fetch(). What gives?
Is this just not possible with AsyncHttpTestCase? What is the best pattern for doing this?
Here's tests.py
import urllib2
from tornado.httpclient import AsyncHTTPClient
import tornado.testing
from tornado.testing import AsyncTestCase, AsyncHTTPTestCase
from app import DebugApp
class TestDebug(AsyncHTTPTestCase):
def get_app(self):
return DebugApp()
def test_foo(self):
response = self.fetch('/foo')
print response.body
assert response.body == 'derp'
def test_foo_from_urllib(self):
response = urllib2.urlopen(self.get_url('/foo'), None, 2)
print response
assert response.body == 'derp'
def runTest(self):
pass
and app.py
import tornado.httpserver
import tornado.ioloop
import tornado.web
from tornado.options import options
class FooHandler(tornado.web.RequestHandler):
def get(self):
self.write("derp")
url_patterns = [
(r"/foo", FooHandler),
]
class DebugApp(tornado.web.Application):
def __init__(self):
tornado.web.Application.__init__(self, url_patterns, debug=True, xsrf_cookies=False)
def main():
app = DebugApp()
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(6006)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
and runtest.py
#!/usr/bin/env python
import unittest
from os import path
import sys
import tornado.testing
PROJECT_PATH = path.dirname(path.abspath(__file__))
sys.path.append(PROJECT_PATH)
def all():
suite = unittest.defaultTestLoader.discover('./', 'tests.py', path.dirname(path.abspath(__file__)))
print suite
return suite
if __name__ == '__main__':
# Print a nice message so that we can differentiate between test runs
print ''
print '%s %s' % ('Debug app', '0.1.0')
print '\033[92m' + '-------------- Running Test Suite --------------' + '\033[0m'
print ''
tornado.testing.main()
The problem is that the IOLoop is not running when you call urlopen (and it cannot be, because urlopen is a blocking function). You must run the IOLoop (with either #gen_test, self.wait(), or indirectly via methods like self.fetch()) for the server to respond, and you can only interact with it via non-blocking functions (or if you must use blocking functions like urlopen, run them in a separate thread).

OperationalError no such table in Flask with SQLAlchemy

run.py
if __name__ == '__main__':
config()
app.run()
main.py
import database
app = Flask(__name__)
def config():
app.config.from_object('config.DevConfig')
# Run SQLAlchemy _that uses app.config_ and add entities if in DEBUG mode
database.init_db(app)
import blueprints.auth
app.register_blueprint(blueprints.auth.auth)
database.py
db = None
def init_db(app):
global db
db = SQLAlchemy(app)
from models import User, Interest, Event
if app.config['DEBUG']:
print 'Recreating all db'
db.create_all() # I DO create everything
print 'Loading test data'
... (here I add some Users and etc. and everything works fine - tests pass)
models.py
from database import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
...
blueprints/auth.py
from models import User
auth = Blueprint('auth', __name__)
#auth.route('/')
def index():
return str(User.query.get(1).interests)
And so I get
OperationalError: (OperationalError) no such table: user u'SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.passhash AS user_passhash, user.vk_page AS user_vk_page \nFROM user \nWHERE user.id = ?' (1,)
What am I doing wrong?
For anyone trying to use an in memory database:
from sqlalchemy import create_engine
from sqlalchemy.pool import StaticPool
engine = create_engine(
"sqlite://",
connect_args={"check_same_thread": False},
poolclass=StaticPool
)
There were few things I had to change to make everything work.
replace DATABASE_URI with SQLALCHEMY_DATABASE_URI parametr in config
replace :memory: sqlite address with /tmp/test.db
Now it works fine.

Test fails in tests.py but succeeds in python shell

I'm a newbee to python and django and I can't figure out what I'm doing wrong here.
I have a Site object:
class Site (models.Model):
domain = models.CharField(max_length=30)
support_status = models.CharField(max_length=20, choices= SITE_SUPPORTED_STATUS, blank=False)
requests = models.IntegerField()
objects = SiteManager()
def __unicode__(self):
return u'%s %s' % (self.domain, self.support_status)
And a SiteManager object
class SiteManager(models.Manager):
def supported_site_counts(self):
i = self.filter(support_status__iexact="SUPPORTED").count()
return i
From the console, the method "supported_site_counts()" works just fine
>>(InteractiveConsole)
>>> from bookmark.models import Site, SiteManager
>>> Site.objects.supported_site_counts()
>>>>2012-05-18 18:09:20,027 DEBUG (0.001) SELECT COUNT(*) FROM "bookmark_site" WHERE
>>>>"bookmark_site"."support_status" LIKE SUPPORTED ESCAPE '\' ; args=(u'SUPPORTED',)
>>>>2012-05-18 18:09:20,028 DEBUG Got 1 supported site
>>>>1
But when it's called from a testcase, the count returns as 0
class SiteManagerTest(unittest.TestCase):
def test_supported_site_counts(self):
self.x = False
self.count = Site.objects.supported_site_counts()
logging.debug(self.count)
This is probably because the tests will set up a database separate from your development database to run the tests in. You will need to put testing data in to the testing database, either programmatically or using fixtures.