sqlalchemy,creating an sqlite database if it doesn't exist - python

I am trying out sqlalchemy and i am using this connection string to connect to my databases
engine = create_engine('sqlite:///C:\\sqlitedbs\\database.db')
Does sqlalchemy create an sqlite database for you if one is not already present in a directory it was supposed to fetch the database file?.

Yes,sqlalchemy does create a database for you.I confirmed it on windows using this code
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy import Column, Date, Integer, String
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///C:\\sqlitedbs\\school.db', echo=True)
Base = declarative_base()
class School(Base):
__tablename__ = "woot"
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
Base.metadata.create_all(engine)

As others have posted, SQLAlchemy will do this automatically. I encountered this error, however, when I didn't use enough slashes!
I used SQLALCHEMY_DATABASE_URI="sqlite:///path/to/file.db" when I should have used four slashes: SQLALCHEMY_DATABASE_URI="sqlite:////path/to/file.db"

Linux stored SQLite3 database
database will be create in the same folder as the .py file:
engine = create_engine('sqlite:///school.db', echo=True)
will instantiate the school.db file in the same folder as the .py file.

I found (using sqlite+pysqlite) that if the directory exists, it will create it, but if the directory does not exist it throws an exception:
OperationalError: (sqlite3.OperationalError) unable to open database file
My workaround is to do this, although it feels nasty:
if connection_string.startswith('sqlite'):
db_file = re.sub("sqlite.*:///", "", connection_string)
os.makedirs(os.path.dirname(db_file), exist_ok=True)
self.engine = sqlalchemy.create_engine(connection_string)

#Gandolf's answer was good.
The database is created it when you make any connection with your engine.
Here's an example of doing nothing with a database besides connecting to it, and this will create the database.
from sqlalchemy import create_engine
engine = create_engine('sqlite:///database.db')
with engine.connect() as conn:
pass
Without the engine.connect() or some form of metadata.create_all() the database will not be ceated.

Related

SQLAlchemy Not Creating Tables in Postgres Database

I am having trouble writing tables to a postgres database using SQLAlchemy ORM and Python scripts.
I know the problem has something to do with incorrect Session imports because when I place all the code below into a single file, the script creates the table without trouble.
However, when I break the script up into multiple files (necessary for this project), I receive the error "psycopg2.errors.UndefinedTable: relation "user" does not exist".
I have read many posts here on SO, tried reorganising my files, the function call order, changing from non-scoped to scoped sessions, eliminating and adding Base.metadata.create_all(bind=engine) in various spots, changed how the sessions are organised and created in base.py, as well as other things, but the script still errors and I'm not sure which code sequence is out of order.
The code currently looks like:
base.py:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
# SQLAlchemy requires creating an Engine to interact with our database.
engine = create_engine('postgresql://user:pass#localhost:5432/testdb', echo=True)
# Create a configured ORM 'Session' factory to get a new Session bound to this engine
#_SessionFactory = sessionmaker(bind=engine)
# Use scoped session
db_session = scoped_session(
sessionmaker(
bind=engine,
autocommit=False,
autoflush=False
)
)
# Create a Base class for our classes definitions
Base = declarative_base()
models.py
from sqlalchemy import Column, DateTime, Integer, Text
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
email = Column(Text, nullable=False, unique=True)
name = Column(Text)
date_last_seen = Column(DateTime(timezone=True))
def __init__(self, email, name, date_last_seen):
self.email = email
self.name = name
self.date_last_seen = date_last_seen
inserts.py
from datetime import date
from base import db_session, engine, Base
from models import User
def init_db():
# Generate database schema based on our definitions in model.py
Base.metadata.create_all(bind=engine)
# Extract a new session from the session factory
#session = _SessionFactory()
# Create instance of the User class
alice = User('alice#throughthelooking.glass', 'Alice', date(1865, 11, 26))
# Use the current session to persist data
db_session.add(alice)
# Commit current session to database and close session
db_session.commit()
db_session.close()
print('Initialized the db')
return
if __name__ == '__main__':
init_db()
Thank you for any insight you're able to offer!

Python SQLAlchemy in-memory database connect

I'm creating a in-memory database with python and I want to use SQLAlchemy with it.
All my application is currently working directly with queries to the db.
I've seen multiple ways of connecting but none of it is working. My current attempt stands as:
# Creates an sqlite database in memory
db = Database(filename=':memory:', schema='schema.sql')
db.recreate()
# ORM
engine = create_engine('sqlite:///:memory:')
Base = automap_base()
Base.prepare(engine, reflect=True)
User = Base.classes.user
session = Session(engine)
This gives AttributeError: user. How do I properly connect my database to the SQLAlchemy?
from sqlalchemy import create_engine
from sqlalchemy.orm import registry, Session
engine = create_engine("sqlite+pysqlite:///:memory:", echo=True, future=True)
session = Session(engine)
registry().metadata.create_all(engine)
ATTACH is your friend.
You can attach an in-memory database to the current database session.
E.g.,
db.init('sqlite://')
db.execute("ATTACH DATABASE ':memory:' AS my_database")
db.create_all()

Unable to return Postgres table names in SQL Alchemy

I've created a database, a schema and some tables in pgadmin4. In python with SQL Alchemy, I am unable to return the tables names.
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine(f'postgresql+psycopg2://{pswd["Connection"]["user"]}:{pswd["Connection"]["pw"]}#{pswd["Connection"]["host"]}/{pswd["Connection"]["database"]}')
Session = sessionmaker(bind=engine)
session = Session()
session.execute('SET search_path TO schema_name;')
print(engine.table_names())
I found the "SET search_path TO schema_name" on another question, but its from 2013. I know the tables exist, I've been able to interact with psycopg2 alone. Any glaring reason as to why this may be the case?
Reading the docs, Engine.table_names() accepts the schema to look in as an argument:
print(engine.table_names("schema_name"))
Your SET is executed in a different connection from the one the engine uses.

Creating a mysql database using sqlalchemy

I'm trying to create a mysql database using sqlalchemy.
I have a flask web app which contains an sqlite database. I'm trying to switch over to mysql. I'm fairly new to sqlalchemy and have learned how to create databases via sqlalchemy. However the databases were sqlite databases. I'm trying to use sqlalchemy to create a mysql database and after reading multiple posts i still can't seem to get it.
I've also installed python-mysqldb
Snippets of the original code used to create an sqlite database which was successful.
Base = declarative_base()
class Categories(Base):
__tablename__ = 'categories'
id = Column(Integer, primary_key=True)
name = Column(String, unique=True)
image = Column(String)
link = Column(String)
description = Column(String)
if __name__ =='__main__':
engine = create_engine('sqlite:///app/database/main.db', echo=True)
Base.metadata.create_all(engine)
mysql attempt
if __name__ =='__main__':
engine = create_engine('mysql://user:password#localhost/app/database/main.db', echo=True)
Base.metadata.create_all(engine)
mysql 2nd attempt
if __name__ =='__main__':
engine = create_engine('mysql://user:password#localhost/app/database/main.db', echo=True)
engine.execute("CREATE DATABASE main.db")
engine.execute("USE main.db")
The error i keep receiving.
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1049, "Unknown database 'app/database/main.db'") (Background on this error at: http://sqlalche.me/e/e3q8)
My best guess is that there's clearly something i'm missing about using mysql with sqlalchemy.
Any help to even point me in the right direction would be greatly appreciated.
a) The correct DBURI syntax for mysql is:
mysql://username:password#servername/databasename
b) The database databasename must be created first. So before you run the Python .create_all() you should connect to the db server using the command line mysql client and execute the CREATE DATABASE databasename statement to create an empty database:
$ mysql -u username -p
... type password
> CREATE DATABASE databasename;
c) You should now be able to run the Python code to create the tables in the empty database.

heroku connect to mysql database

I have push a python-django project to heroku and it works well. In my view.py file of django model, I added function that could connect to the local mysql database to retrieve data from the mysql. The function is the view.py is as followed:
#login_required
def results(request):
data=[]
data1 = []
owner = request.user
owner = str(owner)
db = MySQLdb.connect(user='root', db='aaa', passwd='xxxxx', host='localhost')
cursor = db.cursor()
cursor.execute("SELECT search_content, id, title, author, institute, FROM result_split where username = '%s'" % (owner))
data = cursor.fetchall()
db.close()
return render(request, "webdevelop/results.html", {"datas": data})
But when I try to open the page that show the data from mysql database in the deployed heroku website, it show the error:"OperationalError at /results/
(2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")". How could I have this heroku project to connect to my local mysql database? Or I should choose alternative?
Firstly, you need to ensure that the user and password you're using to connect to MySQL is correct and that the user has the correct privileges to work with the selected database.
Then you can check that mysql is accepting connections on localhost.
As for directly addressing the Connection Refused exception, check things like the mysql socket used to communicate with localhost applications like your Django project. The socket must exist and be configured in MySQL.
I also recommend taking a look at something like SQLAlchemy for Python which will help you interact directly with the database using Python objects. For example,
Connecting to the database:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, scoped_session, mapper
from config import DB_URL
"""Database Declaration"""
metadata = MetaData()
Base = declarative_base(name='Base', mapper=mapper, metadata=metadata)
engine = create_engine(DB_URL, pool_recycle=1800)
Session = sessionmaker(bind=engine, autocommit=False, autoflush=True)
session = scoped_session(Session)
You can now use session variable to perform queries and updates using its inherited functions from the SQLAlchemy Session class.
SQLAlchemy also includes a declarative model for telling Python what your tables look like. For example,
class Clinic(Base):
__tablename__ = 'clinic'
clinic_id = Column(Integer, primary_key=True)
clinic_name = Column(VARCHAR)
address = Column(VARCHAR)
city = Column(VARCHAR)
zip = Column(VARCHAR)
phone = Column(VARCHAR)
user_id = Column(VARCHAR)
These examples work well for my projects in Flask and should work well enough in Django.

Categories

Resources